package core

import (
	"fmt"
	"io"
	"path/filepath"
	"sync"
	"time"

	"github.com/linlexing/dbx/ddb"

	"io/ioutil"
	syslog "log"
	"os"

	log "github.com/Sirupsen/logrus"
	"github.com/linlexing/datelogger"
	"github.com/patrickmn/go-cache"
)

const (
	StaticPath      = "static"
	ViewPath        = "views"
	InstitutionPath = "institution"
	FrontBuildPath  = "front/build"
	DeptRoot        = "r"
)

var (
	GlobalCache    = cache.New(5*time.Minute, 30*time.Second)
	DB             ddb.TxDB
	SessionTimeOut float64
	LOG            *datelogger.DateLogger
	TaskWaitGroup  = new(sync.WaitGroup)
	gTempDir       string //由于android 的关系，临时目录需要保存下来
	gDataDir       string //由于android 的关系，数据目录需要保存下来
)

//CreateTempFile 创建一个临时文件，并返回
func CreateTempFile(prefix string) (*os.File, error) {
	return ioutil.TempFile(gTempDir, prefix)
}
func TempDir() string {
	return gTempDir
}
func Close() {
	DB.Close()
	LOG.Close()
}
func DataFile(file string) string {
	return filepath.Join(gDataDir, file)
}

//初始化日志文件，如果已经初始化则跳过
func checkLog() {
	if LOG == nil {
		str, err := os.Executable()
		if err != nil {
			log.Panic(err)
		}
		workDir := filepath.Dir(str)
		flog, err := os.OpenFile(filepath.Join(workDir, "log.txt"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			panic(fmt.Errorf("error opening file: %v", err))
		}
		//将所有的panic信息输出到err文件中，而不是控制台，因为控制台有行数限制
		//https://stackoverflow.com/questions/34772012/capturing-panic-in-golang
		ferr, err := os.OpenFile(filepath.Join(workDir, "err.txt"), os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			panic(fmt.Errorf("error opening file: %v", err))
		}
		redirectStderr(ferr)
		syslog.SetFlags(syslog.LstdFlags | syslog.Llongfile)
		log.SetOutput(io.MultiWriter(os.Stdout, flog))
		log.SetLevel(log.DebugLevel)
		log.SetFormatter(&log.TextFormatter{
			TimestampFormat: "20060102T150405",
		})
		LOG = datelogger.NewDateLog(filepath.Join(workDir, "log"))
	}
}

//Initinal 函数初始化日志及数据库链接
func Initinal(tempDir, dataDir, dbdriver, dbcnt string) {
	gTempDir = tempDir
	gDataDir = dataDir
	checkLog()
	//如果是sqlite3则加上目录名
	if dbdriver == "sqlite3" {
		dbcnt = DataFile(dbcnt)
	}
	DB = InitMetaDB(dbdriver, dbcnt)
	//触发数据库初始化事件
	if len(DBInitFilters) > 0 {
		if err := DBInitFilters[0](DB, DBInitFilters[1:]); err != nil {
			LOG.Panic(err)
		}
	}
	return

}
