package db

import (
	"context"
	"fmt"
	"strings"

	"gorm.io/driver/mysql"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

func New(ctx context.Context, uri string, opts ...Option) (*Client, error) {
	parts := strings.SplitN(uri, "::", 2)

	if len(parts) != 2 {
		return nil, fmt.Errorf("db.Init: opt db uri invalid: %s", uri)
	}

	c := &Client{cfgSqlite: &cfgSqlite{fsType: "file"}}
	for _, f := range opts {
		f(c)
	}

	var (
		err error
		dsn = parts[1]
	)

	switch parts[0] {
	case "sqlite":
		c.dbType = DBTypeSqlite
		err = openSqlite(c, dsn)
	case "mysql":
		c.dbType = DBTypeMysql
		c.cli, err = gorm.Open(mysql.Open(dsn))
	case "postgres":
		c.dbType = DBTypePostgres
		c.cli, err = gorm.Open(postgres.Open(dsn))
	default:
		return nil, fmt.Errorf("db type only support: [sqlite, mysql, postgres], unsupported db type: %s", parts[0])
	}

	if err != nil {
		return nil, fmt.Errorf("db.Init: open %s with dsn:%s, err: %w", parts[0], dsn, err)
	}

	return c, nil
}

func Init(ctx context.Context, uri string, opts ...Option) (err error) {
	if Default, err = New(ctx, uri, opts...); err != nil {
		return err
	}

	return nil
}