package managecenterMgr

import (
	"encoding/json"
	"errors"
	"fmt"

	"Framework/managecenterModel"
	. "Framework/managecenterModel"
	"goutil/logUtil"
	"goutil/webUtil"
)

var (
	serverMap         = make(map[int32]map[int32]*Server, 128)
	serverDistinctMap = make(map[int32]*Server, 1024)
	serverHash        string
)

// 重新加载服务器
func reloadServer(isInit bool) error {
	//logUtil.DebugLog("开始刷新服务器列表")

	url := getManageCenterUrl("/API/ServerList.ashx")

	// 定义请求参数
	postDict := make(map[string]string)
	postDict["GroupType"] = "Mix"
	postDict["HashValue"] = serverHash

	//请求url,请求头
	header := webUtil.GetFormHeader()
	transport := webUtil.NewTransport()
	transport.DisableKeepAlives = true
	transport = webUtil.GetTimeoutTransport(transport, 30)

	statusCode, returnBytes, err := webUtil.PostMapData(url, postDict, header, transport)
	//statusCode, returnBytes, err := webUtil.PostMapData(url, postDict, header, nil)
	if err != nil {
		logUtil.ErrorLog(fmt.Sprintf("获取服务器列表出错，url:%s,错误信息为:%s", url, err))
		return err
	}
	if statusCode != 200 {
		logUtil.ErrorLog(fmt.Sprintf("获取服务器列表出错，url:%s,错误码为:%d", url, statusCode))
		return err
	}

	// 解析返回值
	returnObj := new(ReturnObject)
	if err = json.Unmarshal(returnBytes, &returnObj); err != nil {
		logUtil.ErrorLog(fmt.Sprintf("获取服务器列表出错，反序列化返回值出错，错误信息为：%s, str:%s", err, string(returnBytes)))
		return err
	}

	// 判断返回状态是否成功
	if returnObj.Code != 0 {
		// 数据没有变化，所以没有获取到新的数据，不能算错误。
		if returnObj.Code == 47 || returnObj.Message == "DataNotChanged" {
			//如果本地集合为空，且数据又没变化时，重新初始化一下本地hash值
			if len(serverMap) == 0 {
				serverHash = ""
			}
			return nil
		} else {
			msg := fmt.Sprintf("获取服务器列表出错，返回状态：%d，信息为：%s", returnObj.Code, returnObj.Message)
			logUtil.ErrorLog(msg)
			return errors.New(msg)
		}
	}

	// 解析Data
	tmpServerList := make([]*Server, 0, 1024)
	if data, ok := returnObj.Data.(string); !ok {
		msg := "获取服务器列表出错，返回的数据不是string类型"
		logUtil.ErrorLog(msg)
		return errors.New(msg)
	} else {
		if err = json.Unmarshal([]byte(data), &tmpServerList); err != nil {
			logUtil.ErrorLog(fmt.Sprintf("获取服务器列表出错，反序列化数据出错，错误信息为：%s", err))
			return err
		}
	}

	//logUtil.DebugLog(fmt.Sprintf("刷新服务器信息结束，服务器数量:%d", len(tmpServerList)))

	tmpServerMap := make(map[int32]map[int32]*Server, 128)
	tmpServerDistinctMap := make(map[int32]*Server, 1024)
	for _, item := range tmpServerList {
		// 构造tmpServerMap数据
		if _, ok := tmpServerMap[item.PartnerId]; !ok {
			tmpServerMap[item.PartnerId] = make(map[int32]*Server, 1024)
		}
		tmpServerMap[item.PartnerId][item.Id] = item

		// 构造tmpServerDistinctMap数据
		tmpServerDistinctMap[item.Id] = item
	}

	// 赋值给最终的serverMap、serverDistinctMap
	serverMap = tmpServerMap
	serverDistinctMap = tmpServerDistinctMap
	serverHash = returnObj.HashValue

	//通知变更
	mcDataChangeCallBack(managecenterModel.ServerData, isInit)

	return nil
}

// 根据服务器组Id获取对应的服务器列表
// serverGroupId:服务器组Id
// 返回值:
// 服务器列表
func GetServerListByGroupId(serverGroupId int32) (serverList []*Server) {
	for _, subServerMap := range serverMap {
		for _, item := range subServerMap {
			if item.GroupId == serverGroupId {
				serverList = append(serverList, item)
			}
		}
	}

	return
}

// 根据合作商Id获取对应的服务器列表
// partnerId:合作商Id
// 返回值:
// 服务器列表
func GetServerListByPartnerId(partnerId int32) (serverList []*Server) {
	for _, item := range serverMap[partnerId] {
		serverList = append(serverList, item)
	}

	return
}

// 根据合作商对象、服务器Id获取服务器对象
// partnerObj：合作商对象
// serverId：服务器Id
// 返回值：
// 服务器对象
// 是否存在
func GetServer(partnerObj *Partner, serverId int32) (serverObj *Server, exist bool) {
	if subServerMap, exist1 := serverMap[partnerObj.Id]; exist1 {
		serverObj, exist = subServerMap[serverId]
	}

	return
}

// 根据合作商Id、服务器Id获取服务器对象
// partnerId：合作商Id
// serverId：服务器Id
// 返回值：
// 服务器对象
// 是否存在
func GetServerItem(partnerId, serverId int32) (serverObj *Server, exist bool) {
	if subServerMap, exist1 := serverMap[partnerId]; exist1 {
		serverObj, exist = subServerMap[serverId]
	}

	return
}

// 获取不重复的服务器Id列表
// 返回值:
// 不重复的服务器Id列表
func GetDistinctServerIdList() (distinctServerIdList []int32) {
	for _, item := range serverDistinctMap {
		distinctServerIdList = append(distinctServerIdList, item.Id)
	}

	return
}
