package main

import (
	"box-gm/utils"
	"fmt"

	"github.com/astaxie/beego"

	// "github.com/drone/routes"
	"box-gm/backup"
	"box-gm/models"
	_ "box-gm/routers"
	"database/sql"
	"log"
	"os"
	"time"

	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	_ "github.com/mattn/go-sqlite3"
)

var dsn = "./admin.db"

func init() {
	//会话保存到文件中
	beego.BConfig.WebConfig.Session.SessionOn = true
}

func TimeToStr(i int64) string {
	if i == int64(0) {
		return ""
	}
	return time.Unix(int64(i), 0).Format("2006-01-02 15:04:05")
}
func GetSelectStatus(id1 int64, id2 int64) string {
	log.Printf("GetSelectStatus id1[%d] id2[%d]", id1, id2)
	if id1 == id2 {
		return "selected"
	}
	return ""
}

// 服务器状态
func ServerStatus(s int) string {
	if s == 1 {
		return "正在运行"
	}
	if s == 0 {
		return "已停止"
	}
	return ""
}

func PermissionToStr(n int64) string {
	ret := ""
	p := models.GetPermissions()
	for i := 0; i < len(p); i++ {
		if (n & (1 << uint(p[i].Id))) != 0 {
			if ret == "" {
				ret = p[i].Name
			} else {
				ret = ret + " | " + p[i].Name
			}
		}
	}

	return ret
}

func GetRoleNameById(id int64) string {
	role := models.GetRoleById(id)
	if role == nil {
		return ""
	}
	return role.Name
}
func TimeCmdOperate(s int) string {
	if s == 1 {
		return "关闭登录"
	}
	if s == 2 {
		return "合服"
	}
	return ""
}
func TimeCmdOperateStatus(s int) string {
	if s == 0 {
		return "未执行"
	}
	if s == 1 {
		return "已执行"
	}
	return ""
}

// 权重物品列表
func WeightItems(items []*models.ExchangeItemsInfo) string {
	cnt := ""
	for _, v := range items {
		if cnt != "" {
			cnt += "|"
		}
		cnt += fmt.Sprintf("%s%d,权重:%d", models.GetItemName(v.ItemId), v.Count, v.Weight)
	}
	return cnt
}

// 道具列表
func BeegoItemNameList(items []int) string {
	cnt := ""
	for _, v := range items {
		if cnt != "" {
			cnt += ","
		}
		cnt += fmt.Sprintf("%s", models.GetItemName(v))
	}
	return cnt
}

// 玩家昵称
func BeegoGetPlayerNickname(uid int) string {
	return utils.GetPlayerNickname(uid)
}

// 初始化beego fun
func initBeegoFunMap() {
	beego.AddFuncMap("TimeToStr", TimeToStr)
	beego.AddFuncMap("GetSelectStatus", GetSelectStatus)
	beego.AddFuncMap("ServerStatus", ServerStatus)
	beego.AddFuncMap("PermissionToStr", PermissionToStr)
	beego.AddFuncMap("GetRoleNameById", GetRoleNameById)
	beego.AddFuncMap("TimeCmdOperate", TimeCmdOperate)
	beego.AddFuncMap("TimeCmdOperateStatus", TimeCmdOperateStatus)
	beego.AddFuncMap("WeightItems", WeightItems)
	beego.AddFuncMap("BeegoItemNameList", BeegoItemNameList)
	beego.AddFuncMap("BeegoGetPlayerNickname", BeegoGetPlayerNickname)
}

func main() {
	//系统第一次初始化需要先运行init
	if len(os.Args) > 1 && os.Args[1] == "init" {
		initDb()
		return
	}
	//当有新数据结构，或者数据结构有变更，需要先运行patch
	if len(os.Args) > 1 && os.Args[1] == "patch" {
		patchDb()
		return
	}
	utils.InitProject()
	utils.InitRedis()

	// 注册sqlite
	orm.RegisterDriver("sqlite3", orm.DRSqlite)
	orm.RegisterDataBase("default", "sqlite3", dsn)
	orm.RegisterDataBase("admin", "sqlite3", dsn)

	go backup.Init_backup_event_proc()

	// 初始化数据
	models.InitHotfixInfo()
	models.InitBanIPInfo()
	models.InitExchangeCodeInfo()
	models.UpdateItemConfig()
	models.UpdateGoodsConfig()
	models.InitRollAwardInfo()
	models.InitRollInfo()

	//模板初始化
	initBeegoFunMap()

	beego.SetLevel(beego.LevelInformational)
	beego.Run()
}

func initDb() {
	os.Remove(dsn)

	orm.RegisterDriver("sqlite3", orm.DRSqlite)
	orm.RegisterDataBase("default", "sqlite3", dsn)
	orm.RegisterDataBase("admin", "sqlite3", dsn)

	db, err := sql.Open("sqlite3", dsn)
	if err != nil {
		panic(err.Error())
	}
	r, err := db.Exec("create table init (n varchar(32));drop table init;")
	if err != nil {
		log.Println(err)
		log.Println(r)
	} else {
		log.Println("Database ", " created")
	}

	o := orm.NewOrm()
	o.Using("admin")
	orm.RunSyncdb("admin", true, true)

	u := new(models.User)
	u.Username = "admin"
	u.Role = 1
	u.Password = utils.Strtomd5("000000")
	u.CreateTs = time.Now().Unix()
	u.LastLoginTs = time.Now().Unix()
	o.Insert(u)

	role := new(models.Role)
	role.Name = "管理员"
	role.Permission = 0xFFFFFFFF
	o.Insert(role)

	time.Sleep(10000)
}

func patchDb() {
	orm.RegisterDriver("sqlite3", orm.DRSqlite)
	orm.RegisterDataBase("default", "sqlite3", dsn)
	orm.RegisterDataBase("admin", "sqlite3", dsn)

	//force - drop table 后再建表
	orm.RunSyncdb("admin", false, true)

	// o := orm.NewOrm()
	// o.Insert(&models.SystemParameter{Key: "test_server", Value: ""})
	// o.Insert(&models.SystemParameter{Key: "game_server", Value: ""})
}
