package setting

import (
	"flag"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/pkg/errors"

	"github.com/go-ini/ini"
	"github.com/jacobsa/go-serial/serial"
)

var AppSetting = &App{}
var ServerSetting = &Server{}
var CommSetting = &serial.OpenOptions{}

type App struct {
	JwtSecret string
	PageSize  int
	PrefixUrl string

	RuntimeRootPath string

	FileSavePath  string
	FileMaxSize   int      // 普通文件上传的限制大小,单位byte, 最大单位1GB
	FileAllowType []string // 允许上传的文件后缀名

	ImageSavePath  string
	ImageMaxSize   int
	ImageAllowExts []string

	ThumbnailSavePath  string
	ThumbnailMaxWidth  int
	ThumbnailMaxHeight int

	ExportSavePath string
	QrCodeSavePath string
	FontSavePath   string

	LogSavePath string
	LogSaveName string
	LogFileExt  string
	TimeFormat  string
}

type Server struct {
	Env              string
	RunMode          string
	HttpPort         int
	ReadTimeout      time.Duration
	WriteTimeout     time.Duration
	NoAuth           int
	Mdns_servicename string
	Mdns_serviceport int
	HttpsPort        int
	Https            int
	CrtPath          string
	KeyPath          string
	MailStart        string
	CronFormula      string
	WXworkStart      string
	WXworkAgentid    string
	WXworkSecret     string
	WXworkCorpid     string

	DingTalkToken          string
	DingTalkEncodingAESKey string
	DingTalkAppKey         string
	DingTalkAppSecret      string
	DingTalkAgentid        string

	ServerName  string
	DisplayName string
	Description string

	EasName     string
	EasPassword string
	EasUrl      string
	EasUrlTem   string
}

type Database struct {
	Type          string
	User          string
	Password      string
	Host          string
	Name          string
	ShowXormlog   bool
	ShowGetSqllog bool
	CacheApiSql   bool
	TablePrefix   string
	Dsn           string
}

type SQlServer struct {
	Host     string
	User     string
	Password string
	Name     string
}

var DatabaseSetting = &Database{}

var SQlServerSetting = &SQlServer{}

var cfg *ini.File

var CurrentPath string

func init() {
	flag.StringVar(&CurrentPath, "iconf", "", "default config path")
}
func GetCurrentPath() (string, error) {
	file, err := exec.LookPath(os.Args[0])
	if err != nil {
		return "", err
	}
	path, err := filepath.Abs(file)
	if err != nil {
		return "", err
	}
	if runtime.GOOS == "windows" {
		path = strings.Replace(path, "\\", "/", -1)
	}
	i := strings.LastIndex(path, "/")
	if i < 0 {
		return "", errors.New(`Can't find "/" or "\".`)
	}
	return string(path[0 : i+1]), nil
}
func Setup(dir string) {

	var err error
	if strings.Trim(dir, " ") == "" {
		CurrentPath, err = GetCurrentPath()
	} else {
		CurrentPath = dir
	}
	cfg, err = ini.Load(CurrentPath + "conf/app.ini")
	if err != nil {
		log.Fatalf("setting.Setup, fail to parse 'conf/app.ini' CurrentPath: %s,Err: %v", CurrentPath, err)
		panic(err)
	}
	DatabaseSetting.ShowXormlog = false
	DatabaseSetting.ShowGetSqllog = false
	DatabaseSetting.CacheApiSql = false
	mapTo("app", AppSetting)
	mapTo("server", ServerSetting)
	mapTo("database", DatabaseSetting)
	mapTo("comm", CommSetting)
	mapTo("sqlserver", SQlServerSetting)

	AppSetting.ImageMaxSize = AppSetting.ImageMaxSize * 1024 * 1024
	ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second
	ServerSetting.WriteTimeout = ServerSetting.ReadTimeout * time.Second

	ServerSetting.CrtPath = CurrentPath + ServerSetting.CrtPath
	ServerSetting.KeyPath = CurrentPath + ServerSetting.KeyPath

}

func mapTo(section string, v interface{}) {
	err := cfg.Section(section).MapTo(v)
	if err != nil {
		log.Fatalf("Cfg.MapTo RedisSetting err: %v", err)
	}
}