package userstore

import (
	"database/sql"
	_ "embed"
	"fmt"
	"os"
	"strings"

	"git.keks.cloud/kekskurse/miniauth/pkg/utils"
	"github.com/google/uuid"
	"github.com/rs/zerolog"

	_ "github.com/tursodatabase/libsql-client-go/libsql"
	_ "modernc.org/sqlite"
)

//go:embed migrations/schema.sql
var schema string

type Config struct {
	SQLite struct {
		Path string `env:"SQLITE_PATH"`
	}
	Logger zerolog.Logger
}

type Store struct {
	log zerolog.Logger
	db  *sql.DB
}

func NewStore(c Config) (Store, error) {
	log := c.Logger.With().Str("pkg", "userstore").Str("sqlitePath", c.SQLite.Path).Logger()

	db, err := sql.Open("libsql", c.SQLite.Path)
	if err != nil {
		return Store{}, utils.WrapError(ErrCantOpenDatabase, err, log)
	}

	err = db.Ping()
	if err != nil {
		return Store{}, utils.WrapError(ErrCantOpenDatabase, err, log)
	}

	s := Store{
		db:  db,
		log: log,
	}

	return s, nil
}

func NewDummyStore() (Store, error) {
	name, err := os.MkdirTemp("", "miniauth-teststore")
	if err != nil {
		return Store{}, err
	}

	c := Config{}
	c.SQLite.Path = fmt.Sprintf("file://%v/%v.sqlite", name, uuid.NewString())

	store, err := NewStore(c)
	if err != nil {
		return Store{}, err
	}

	newSchema := strings.Replace(schema, "CREATE TABLE sqlite_sequence(name,seq);", "", 1)
	_, err = store.db.Exec(newSchema)
	if err != nil {
		return Store{}, err
	}

	return store, nil
}