package setting

import (
	"chain33-pai/pkg/chain33"
	"github.com/33cn/chain33/types"
	"github.com/go-ini/ini"
	"log"
	"os/exec"
	"time"
)

var PaiClient *chain33.PaiClient
var ReverseTunnelPort string

type App struct {
	JwtSecret string
	PageSize  int
	PrefixUrl string

	RuntimeRootPath string

	ImageSavePath  string
	ImageMaxSize   int
	ImageAllowExts []string

	ExportSavePath string
	QrCodeSavePath string
	FontSavePath   string

	LogSavePath string
	LogSaveName string
	LogFileExt  string
	TimeFormat  string
}

var AppSetting = &App{}

type Server struct {
	RunMode      string
	HttpPort     int
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
}

var ServerSetting = &Server{}

type Database struct {
	Type        string
	User        string
	Password    string
	Host        string
	Name        string
	TablePrefix string
}

var DatabaseSetting = &Database{}

type Redis struct {
	Host        string
	Password    string
	MaxIdle     int
	MaxActive   int
	IdleTimeout time.Duration
}

var RedisSetting = &Redis{}

type Bityuan struct {
	Path        string
	Name        string
	GitPath     string
	Passwd      string
	Version     string
	VersionPath string
}

var BityuanSetting = &Bityuan{}

type Chain33_pai struct {
	Name               string
	Path               string
	Auto               string
	Start              string
	StartUp            string
	Scripts            string
	DownloadUrl        string
	VersionUrl         string
	FeedBackUrl        string
	IsCompleteUrl      string
	FeedBackNosshUrl   string
	IsCompleteNosshUrl string
	RaspberryServer    string
	StopPai            string
	UploadVersionUrl   string
	UploadTestUrl      string
	VersionTestUrl     string
	Env                string
}

var Chain33Pai = &Chain33_pai{}

var LogSetting = &types.Log{}

var cfg *ini.File

// Setup initialize the configuration instance
func Setup() {
	var err error
	cfg, err = ini.Load("conf/app.ini")
	if err != nil {
		log.Fatalf("setting.Setup, fail to parse 'conf/app.ini': %v", err)
	}
	mapTo("app", AppSetting)
	mapTo("redis", RedisSetting)
	mapTo("server", ServerSetting)
	mapTo("chain33-pai", Chain33Pai)
	mapTo("bityuan", BityuanSetting)
	mapTo("database", DatabaseSetting)
	mapTo("log", LogSetting)
	AppSetting.ImageMaxSize = AppSetting.ImageMaxSize * 1024 * 1024
	ServerSetting.ReadTimeout = ServerSetting.ReadTimeout * time.Second
	ServerSetting.WriteTimeout = ServerSetting.WriteTimeout * time.Second
	RedisSetting.IdleTimeout = RedisSetting.IdleTimeout * time.Second

}

func FreshVersion() {
	version, err := PaiClient.Version()
	if err != nil {
		auto := exec.Command(Chain33Pai.Auto)
		err = auto.Start()
		if err != nil {
			log.Fatalf("start node failed,need to start manually")
		}
		err = auto.Wait()
		if err != nil {
			log.Fatalf("start node failed,need to start manually")
		}
	}
	BityuanSetting.Version = version.App
}

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

}
