package main

import (
	"Server-Core/Server/Base"
	"fmt"
	"net"
	"os"
)

func WriteS(f *os.File, s []byte) bool {
	_, err := f.Write(s)
	if err != nil {
		fmt.Println(err)
		return false
	}
	return true
}

func GeneratorDef() bool {
	//file, err := os.OpenFile("../../Server/Scheme/SchemeDef.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	//files, _ = ioutil.ReadDir("E://ChatGameService2/Server/Scheme")
	file, err := os.OpenFile("../../Server/Scheme/SchemeDef.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		fmt.Println(err)
		return false
	}
	defer file.Close()

	var s = "package scheme\n\n"
	s += "type ID int32\n"
	s += "type G int32\n\n"
	s += "const (\n\t"
	s += "ID_Min = iota\n\t"
	for _, name := range FileList {
		s += "ID_" + name + "\n\t"
	}
	s += "ID_Max\n"
	s += ")\n\n"
	s += "const (\n"
	//records := base.LoadCsvCfg("../../Bin/Scp/Rule.csv").Records
	//records := base.LoadCsvCfg("./Scp/Rule.csv").Records
	var path string = ""
	if ip == "192.168.1.122" {
		path = "E://ChatGameService2/Bin/Scp/Role.csv"
	} else {
		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
		path = "../Scp/Level.csv"
	}
	records := base.LoadCsvCfg(path).Records
	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Rule.csv").Records
	for i := 4; i < len(records); i++ {
		s += "\tG_" + records[i].Record["name"] + " = " + records[i].Record["id"] + "\n"
	}
	s += ")\n\n"
	s += "type Scp interface {\n\t"
	s += "Load()\n\t"
	s += "Get(key int32) (interface{}, error)\n"
	s += "}\n\n"
	s += "func Register() {\n"
	for _, name := range FileList {
		s += "\tmgr.schemeList[ID_" + name + "] = new(" + name + ")\n"
	}
	s += "}"

	if !WriteS(file, []byte(s)) {
		return false
	}

	return true
}

var ip string = ""

func getIp() string {

	addrList, err := net.InterfaceAddrs()
	if err != nil {
		panic(err)
	}
	for _, address := range addrList {
		if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
			if ipNet.IP.To4() != nil {
				fmt.Println(ipNet.IP.String())
				ip = ipNet.IP.String()
				break
			}
		}
	}
	return ip
}
func GeneratorScp() bool {
	for _, name := range FileList {
		fileName := "Scheme" + name + ".go"
		if SchemeMap[name] == true {
			fmt.Println(fileName + "已经存在, 忽略")
			continue
		}

		fmt.Println("开始生成" + fileName)
		file, err := os.OpenFile("../../Server/Scheme/"+fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
		if err != nil {
			fmt.Println(err)
			return false
		}

		var s = "package scheme\n\n"
		s += "import (\n\t"
		s += "\"Server-Core/Server/Base\"\n\t"
		s += "\"reflect\"\n\t"
		s += "\"strconv\"\n"
		s += ")\n\n"
		s += "type " + name + "Item struct {\n"
		//r := base.LoadCsvCfg("../../Bin/Scp/" + name + ".csv")
		var path string = ""
		if ip == "192.168.1.122" {
			path = "E://ChatGameService2/Bin/Scp/" + name + ".csv"
		} else {
			//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
			path = "./Scp/" + name + ".csv"
		}

		if ip == "192.168.1.122" {
			path = "E://ChatGameService2/Bin/Scp/" + name + ".csv"
		} else {
			//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
			path = "./Scp/" + name + ".csv"
		}
		r := base.LoadCsvCfg(path)
		//	r := base.LoadCsvCfg("./Scp/" + name + ".csv")
		//r := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/" + name + ".csv")
		records := r.Records
		primaryKey := ""
		for k, v := range records[1].Record {
			key := base.StrFirstToUpper(k)
			if k == r.Key {
				primaryKey = key
			}
			var value string
			switch v {
			case "INT":
				value = "int32"
			case "FLOAT":
				value = "float64"
			case "STRING":
				value = "string"
			default:
				fmt.Println("类型异常: " + v)
				return false
			}
			s += "\t" + key + " " + value + "\n"
		}
		s += "}\n\n"
		s += "type " + name + " struct {\n\t"
		s += "dataList map[int32]*" + name + "Item\n"
		s += "}\n\n"
		s += "func (scp *" + name + ") Load() {\n\t"
		s += "scp.dataList = make(map[int32]*" + name + "Item)\n\t"
		s += "records := base.LoadCsvCfg(\"../Scp/" + name + ".csv\").Records\n\t"
		s += "for i := 4; i < len(records); i++ {\n\t\t"
		s += "item := new(" + name + "Item)\n\t\t"
		s += "cr := reflect.ValueOf(item).Elem()\n\t\t"
		s += "for k, v := range records[i].Record {\n\t\t\t"
		s += "k = base.StrFirstToUpper(k)\n\t\t\t"
		s += "a := cr.FieldByName(k)\n\t\t\t"
		s += "switch a.Type().String() {\n\t\t\t"
		s += "case \"string\":\n\t\t\t\t"
		s += "a.Set(reflect.ValueOf(v))\n\t\t\t"
		s += "case \"int32\":\n\t\t\t\t"
		s += "i, _ := strconv.Atoi(v)\n\t\t\t\t"
		s += "a.Set(reflect.ValueOf(int32(i)))\n\t\t\t"
		s += "case \"float64\":\n\t\t\t\t"
		s += "f, _ := strconv.ParseFloat(v, 64)\n\t\t\t\t"
		s += "a.Set(reflect.ValueOf(f))\n\t\t\t"
		s += "}\n\t\t"
		s += "}\n\t\t"
		s += "scp.dataList[item." + primaryKey + "] = item\n\t"
		s += "}\n"
		s += "}\n\n"
		s += "func (scp *" + name + ") Get(key int32) interface{} {\n\t"
		s += "return scp.dataList[key]\n"
		s += "}"

		if !WriteS(file, []byte(s)) {
			return false
		}

		file.Close()
	}

	return true
}
