package config

import "fmt"

type DriverType string

const (
	MySQL    DriverType = "mysql"
	Postgres DriverType = "postgres"
	SQLite   DriverType = "sqlite"
)

// DatabaseConfig will hold the database configuration.
//
// If the driver is SQLite, the Host field should be the path to the database file.
// Other configurations options will be ignored.
type DatabaseConfig struct {
	Driver DriverType `json:"driver" yaml:"driver" toml:"driver" validate:"required"`
	Host   string     `json:"host" yaml:"host" toml:"host" validate:"required"`
	Port   int        `json:"port" yaml:"port" toml:"port"`
	User   string     `json:"user" yaml:"user" toml:"user"`
	Pass   string     `json:"pass" yaml:"pass" toml:"pass"`
	DBName string     `json:"db_name" yaml:"db_name" toml:"db_name"`
}

func NewDatabaseConfig(driver *DriverType, host, user, pass, dbName *string, port *int) DatabaseConfig {
	defaultDriver := SQLite
	defaultHost := "./database.db"
	defaultPort := 0
	defaultUser := ""
	defaultPass := ""
	defaultDBName := ""

	if driver == nil {
		driver = &defaultDriver
	}
	if host == nil {
		host = &defaultHost
	}
	if port == nil {
		port = &defaultPort
	}
	if user == nil {
		user = &defaultUser
	}
	if pass == nil {
		pass = &defaultPass
	}
	if dbName == nil {
		dbName = &defaultDBName
	}

	return DatabaseConfig{
		Driver: *driver,
		Host:   *host,
		Port:   *port,
		User:   *user,
		Pass:   *pass,
		DBName: *dbName,
	}
}

// GenerateDSN generates the Data Source Name (DSN) for the database connection.
func (c *DatabaseConfig) GenerateDSN() string {
	switch c.Driver {
	case MySQL:
		return c.generateMySQLDSN()
	case Postgres:
		return c.generatePostgresDSN()
	case SQLite:
		return c.generateSQLiteDSN()
	default:
		return ""
	}
}

func (c *DatabaseConfig) GetDriver() string {
	switch c.Driver {
	case MySQL:
		return "mysql"
	case Postgres:
		return "pgx"
	case SQLite:
		return "sqlite3"
	default:
		return ""
	}
}

func (c *DatabaseConfig) generateSQLiteDSN() string {
	return c.Host
}
func (c *DatabaseConfig) generateMySQLDSN() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", c.User, c.Pass, c.Host, c.Port, c.DBName)
}
func (c *DatabaseConfig) generatePostgresDSN() string {
	return fmt.Sprintf("postgres://%s:%s@%s:%d/%s", c.User, c.Pass, c.Host, c.Port, c.DBName)
}