package core

import (
	"fmt"

	"github.com/linlexing/dbx/ddb"

	cache "github.com/patrickmn/go-cache"
)

var metaDB ddb.TxDB
var outerdbCache = cache.New(cache.NoExpiration, cache.NoExpiration)

//OuterDBList 返回所有的数据库
func OuterDBList(db ddb.DB) []*ModelOuterDB {
	out := []*ModelOuterDB{}
	md, err := NewModel(db, ModelOuterdbName)
	if err != nil {
		LOG.Panic(err)
	}

	rows, err := md.QueryOrder([]string{"NAME"}, "")
	if err != nil {
		LOG.Panic(err)
	}
	defer rows.Close()
	for rows.Next() {
		var oneDB ModelOuterDB
		if err := rows.Scan(&oneDB); err != nil {
			LOG.Panic(err)
		}
		out = append(out, &oneDB)
	}
	return out
}

//OuterDBExists 检查是否存在
func OuterDBExists(db ddb.DB, name string) bool {
	//空字符串代表当前数据库，永远是存在
	if len(name) == 0 {
		return true
	}
	md, err := NewModel(db, ModelOuterdbName)
	if err != nil {
		LOG.Panic(err)
	}
	b, err := md.KeyExists(name)
	if err != nil {
		LOG.Panic(err)
	}
	return b
}

func InitMetaDB(driver, connectString string) ddb.TxDB {
	var err error
	metaDB, err = ddb.Openx(driver, connectString)
	if err != nil {
		LOG.Println("driver:", driver, "cnt:", connectString)
		LOG.Panic(err)
	}
	//sqlite3必须设置临时目录，否则android出错
	if driver == "sqlite3" {
		if _, err = metaDB.Exec(fmt.Sprintf("PRAGMA temp_store_directory = '%s'", TempDir())); err != nil {
			LOG.Panic(err)
		}
	}
	LOG.Printf("open database drive %s ,connection string:%s\n", driver, connectString)
	initModels(metaDB)
	initControllers(metaDB)
	return metaDB
}

//LoadOuterDB 创建一个数据库连接
func LoadOuterDB(db ddb.DB, name string) ddb.TxDB {
	if name == "" {
		return metaDB
	}
	if r, ok := outerdbCache.Get(name); ok {
		return r.(ddb.TxDB)
	}
	var out ModelOuterDB
	md, err := NewModel(db, ModelOuterdbName)
	if err != nil {
		LOG.Panic(err)
	}
	if err = md.Get(&out, name); err != nil {
		LOG.Panic(err)
	}

	r, err := ddb.Openx(out.Driver, out.CntStr)
	if err != nil {
		LOG.Panic(err)
	}
	//sqlite3 需要设置临时目录，主要是android需要
	if out.Driver == "sqlite3" {
		if _, err = metaDB.Exec(fmt.Sprintf("PRAGMA temp_store_directory = '%s'", TempDir())); err != nil {
			LOG.Panic(err)
		}
	}
	outerdbCache.Set(name, r, 0)
	return r

}
func RemoveOuterDBFromCache(name string) {
	outerdbCache.Delete(name)
}
