// Copyright (c) 2018 David Crawshaw <david@zentus.com>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

package sqlite

// #include <sqlite3.h>
import "C"
import (
	"fmt"
	"strings"
)

// OpenFlags are flags used when opening a Conn.
//
// https://www.sqlite.org/c3ref/c_open_autoproxy.html
type OpenFlags int

const (
	SQLITE_OPEN_READONLY       OpenFlags = C.SQLITE_OPEN_READONLY
	SQLITE_OPEN_READWRITE      OpenFlags = C.SQLITE_OPEN_READWRITE
	SQLITE_OPEN_CREATE         OpenFlags = C.SQLITE_OPEN_CREATE
	SQLITE_OPEN_DELETEONCLOSE  OpenFlags = C.SQLITE_OPEN_DELETEONCLOSE
	SQLITE_OPEN_EXCLUSIVE      OpenFlags = C.SQLITE_OPEN_EXCLUSIVE
	SQLITE_OPEN_AUTOPROXY      OpenFlags = C.SQLITE_OPEN_AUTOPROXY
	SQLITE_OPEN_URI            OpenFlags = C.SQLITE_OPEN_URI
	SQLITE_OPEN_MEMORY         OpenFlags = C.SQLITE_OPEN_MEMORY
	SQLITE_OPEN_MAIN_DB        OpenFlags = C.SQLITE_OPEN_MAIN_DB
	SQLITE_OPEN_TEMP_DB        OpenFlags = C.SQLITE_OPEN_TEMP_DB
	SQLITE_OPEN_TRANSIENT_DB   OpenFlags = C.SQLITE_OPEN_TRANSIENT_DB
	SQLITE_OPEN_MAIN_JOURNAL   OpenFlags = C.SQLITE_OPEN_MAIN_JOURNAL
	SQLITE_OPEN_TEMP_JOURNAL   OpenFlags = C.SQLITE_OPEN_TEMP_JOURNAL
	SQLITE_OPEN_SUBJOURNAL     OpenFlags = C.SQLITE_OPEN_SUBJOURNAL
	SQLITE_OPEN_MASTER_JOURNAL OpenFlags = C.SQLITE_OPEN_MASTER_JOURNAL
	SQLITE_OPEN_NOMUTEX        OpenFlags = C.SQLITE_OPEN_NOMUTEX
	SQLITE_OPEN_FULLMUTEX      OpenFlags = C.SQLITE_OPEN_FULLMUTEX
	SQLITE_OPEN_SHAREDCACHE    OpenFlags = C.SQLITE_OPEN_SHAREDCACHE
	SQLITE_OPEN_PRIVATECACHE   OpenFlags = C.SQLITE_OPEN_PRIVATECACHE
	SQLITE_OPEN_WAL            OpenFlags = C.SQLITE_OPEN_WAL
	SQLITE_OPEN_NOFOLLOW       OpenFlags = C.SQLITE_OPEN_NOFOLLOW

	OpenFlagsDefault = SQLITE_OPEN_READWRITE |
		SQLITE_OPEN_CREATE |
		SQLITE_OPEN_WAL |
		SQLITE_OPEN_URI |
		SQLITE_OPEN_NOMUTEX
)

var allOpenFlags = []OpenFlags{
	SQLITE_OPEN_READONLY,
	SQLITE_OPEN_READWRITE,
	SQLITE_OPEN_CREATE,
	SQLITE_OPEN_DELETEONCLOSE,
	SQLITE_OPEN_EXCLUSIVE,
	SQLITE_OPEN_AUTOPROXY,
	SQLITE_OPEN_URI,
	SQLITE_OPEN_MEMORY,
	SQLITE_OPEN_MAIN_DB,
	SQLITE_OPEN_TEMP_DB,
	SQLITE_OPEN_TRANSIENT_DB,
	SQLITE_OPEN_MAIN_JOURNAL,
	SQLITE_OPEN_TEMP_JOURNAL,
	SQLITE_OPEN_SUBJOURNAL,
	SQLITE_OPEN_MASTER_JOURNAL,
	SQLITE_OPEN_NOMUTEX,
	SQLITE_OPEN_FULLMUTEX,
	SQLITE_OPEN_SHAREDCACHE,
	SQLITE_OPEN_PRIVATECACHE,
	SQLITE_OPEN_WAL,
	SQLITE_OPEN_NOFOLLOW,
}

var openFlagsStrings = map[OpenFlags]string{
	SQLITE_OPEN_READONLY:       "SQLITE_OPEN_READONLY",
	SQLITE_OPEN_READWRITE:      "SQLITE_OPEN_READWRITE",
	SQLITE_OPEN_CREATE:         "SQLITE_OPEN_CREATE",
	SQLITE_OPEN_DELETEONCLOSE:  "SQLITE_OPEN_DELETEONCLOSE",
	SQLITE_OPEN_EXCLUSIVE:      "SQLITE_OPEN_EXCLUSIVE",
	SQLITE_OPEN_AUTOPROXY:      "SQLITE_OPEN_AUTOPROXY",
	SQLITE_OPEN_URI:            "SQLITE_OPEN_URI",
	SQLITE_OPEN_MEMORY:         "SQLITE_OPEN_MEMORY",
	SQLITE_OPEN_MAIN_DB:        "SQLITE_OPEN_MAIN_DB",
	SQLITE_OPEN_TEMP_DB:        "SQLITE_OPEN_TEMP_DB",
	SQLITE_OPEN_TRANSIENT_DB:   "SQLITE_OPEN_TRANSIENT_DB",
	SQLITE_OPEN_MAIN_JOURNAL:   "SQLITE_OPEN_MAIN_JOURNAL",
	SQLITE_OPEN_TEMP_JOURNAL:   "SQLITE_OPEN_TEMP_JOURNAL",
	SQLITE_OPEN_SUBJOURNAL:     "SQLITE_OPEN_SUBJOURNAL",
	SQLITE_OPEN_MASTER_JOURNAL: "SQLITE_OPEN_MASTER_JOURNAL",
	SQLITE_OPEN_NOMUTEX:        "SQLITE_OPEN_NOMUTEX",
	SQLITE_OPEN_FULLMUTEX:      "SQLITE_OPEN_FULLMUTEX",
	SQLITE_OPEN_SHAREDCACHE:    "SQLITE_OPEN_SHAREDCACHE",
	SQLITE_OPEN_PRIVATECACHE:   "SQLITE_OPEN_PRIVATECACHE",
	SQLITE_OPEN_WAL:            "SQLITE_OPEN_WAL",
	SQLITE_OPEN_NOFOLLOW:       "SQLITE_OPEN_NOFOLLOW",
}

func (o OpenFlags) String() string {
	var flags []string
	for _, flag := range allOpenFlags {
		if o&flag == 0 {
			continue
		}
		flagStr, ok := openFlagsStrings[flag]
		if !ok {
			flagStr = fmt.Sprintf("UNKNOWN FLAG: %x", flag)
		}
		flags = append(flags, flagStr)
	}
	return strings.Join(flags, "|")
}
