package main

import (
	"strconv"
	"time"

	"mongo.games.com/goserver/core/logger"
	"mongo.games.com/goserver/core/module"
	"mongo.games.com/goserver/core/netlib"
	"mongo.games.com/goserver/core/utils"
	srvlibproto "mongo.games.com/goserver/srvlib/protocol"

	"mongo.games.com/game/model"
	"mongo.games.com/game/proto"
	hallproto "mongo.games.com/game/protocol/gamehall"
	loginproto "mongo.games.com/game/protocol/login"
	serverproto "mongo.games.com/game/protocol/server"
	webapiproto "mongo.games.com/game/protocol/webapi"
	"mongo.games.com/game/srvdata"
)

const (
	DefaultPlatform    = "0"
	DefaultPlatformInt = 0
)

// PlatformConfig 所有跟平台相关的配置，不要再定义map数据结构了
type PlatformConfig struct {
	Platform      *Platform                     // 平台配置
	EntrySwitch   *webapiproto.EntrySwitch      // 客户端游戏入口开关
	CommonNotices *webapiproto.CommonNoticeList // 公告
	PlayerPool    *webapiproto.PlayerPool       // 个人水池配置
}

type PlatformObserver interface {
	OnPlatformCreate(p *Platform)
	OnPlatformDestroy(p *Platform)
	OnPlatformChangeDisabled(p *Platform, disabled bool)
	OnPlatformGameFreeUpdate(p *Platform, oldCfg, newCfg *webapiproto.GameFree)
	OnPlatformDestroyByGameFreeId(p *Platform, gameFreeId int32)
}

var PlatformMgrSingleton = &PlatformMgr{
	configs:     make(map[string]*PlatformConfig),
	PackageList: make(map[string]*webapiproto.AppInfo),
	GameStatus:  make(map[int32]bool), //全局游戏开关
}

type PlatformMgr struct {
	BaseClockSinker

	//todo 所有跟平台相关的配置，不要再定义map数据结构了
	configs map[string]*PlatformConfig

	PackageList map[string]*webapiproto.AppInfo // 包对应的平台，包标识
	GameStatus  map[int32]bool                  // 超管平台游戏开关，游戏id

	Observers []PlatformObserver
}

func (pm *PlatformMgr) RegisterObserver(observer PlatformObserver) {
	for _, ob := range pm.Observers {
		if ob == observer {
			return
		}
	}
	pm.Observers = append(pm.Observers, observer)
}

func (pm *PlatformMgr) UnregisterObserver(observer PlatformObserver) {
	for i, ob := range pm.Observers {
		if ob == observer {
			pm.Observers = append(pm.Observers[:i], pm.Observers[i+1:]...)
			break
		}
	}
}

func (pm *PlatformMgr) GetPlatforms() []*Platform {
	var ret []*Platform
	for _, v := range pm.configs {
		if v != nil && v.Platform != nil {
			ret = append(ret, v.Platform)
		}
	}
	return ret
}

func (pm *PlatformMgr) CreatePlatform(id int32, isolated bool) *Platform {
	pltId := strconv.Itoa(int(id))
	p := NewPlatform(id, isolated)
	pm.Get(pltId).Platform = p
	if p != nil {
		pm.OnPlatformCreate(p)
	}
	return p
}

// CreateDefaultPlatform 创建默认平台
func (pm *PlatformMgr) CreateDefaultPlatform() {
	//默认平台数据
	defaultPlatform := pm.CreatePlatform(DefaultPlatformInt, false)
	defaultPlatform.Disable = false
	//默认平台配置
	pgc := defaultPlatform.PltGameCfg
	if pgc != nil {
		for _, value := range srvdata.PBDB_GameFreeMgr.Datas.Arr {
			if value.GetGameId() > 0 {
				pgc.games[value.GetId()] = &webapiproto.GameFree{
					Status:     true,
					DbGameFree: value,
				}
			}
		}
		pgc.RecreateCache()
	}
}

// UpsertPlatform 更新或新增平台
func (pm *PlatformMgr) UpsertPlatform(name string, isolated, disable bool, id int32, url string,
	bindOption int32, serviceFlag bool, upgradeAccountGiveCoin, newAccountGiveCoin, perBankNoLimitAccount, exchangeMin,
	exchangeLimit, exchangeTax, exchangeFlow, exchangeFlag, spreadConfig int32, vipRange []int32, otherParam string,
	ccf *ClubConfig, verifyCodeType int32, thirdState map[int32]int32, customType int32, needDeviceInfo bool,
	needSameName bool, exchangeForceTax int32, exchangeGiveFlow int32, exchangeVer int32, exchangeBankMax int32,
	exchangeAlipayMax int32, dgHboCfg int32, PerBankNoLimitName int32, isCanUserBindPromoter bool,
	userBindPromoterPrize int32, spreadWinLose bool, exchangeMultiple int32, registerVerifyCodeSwitch bool, merchantKey string,
	bindTelReward map[int32]int64) *Platform {
	pltId := strconv.Itoa(int(id))
	p := pm.Get(pltId).Platform
	if p == nil {
		p = pm.CreatePlatform(id, isolated)
	}
	//oldIsolated := p.Isolated
	//oldBindPromoter := p.IsCanUserBindPromoter
	oldDisabled := p.Disable
	//oldBindOption := p.BindOption
	p.Id = id
	p.Name = name
	p.IdStr = pltId
	p.ServiceUrl = url
	p.BindOption = bindOption
	p.ServiceFlag = serviceFlag
	p.CustomType = customType
	p.UpgradeAccountGiveCoin = upgradeAccountGiveCoin
	p.NewAccountGiveCoin = newAccountGiveCoin
	p.PerBankNoLimitAccount = perBankNoLimitAccount
	p.ExchangeMin = exchangeMin
	p.ExchangeLimit = exchangeLimit
	p.SpreadConfig = spreadConfig
	p.ExchangeTax = exchangeTax
	p.ExchangeVer = exchangeVer
	p.ExchangeForceTax = exchangeForceTax
	p.ExchangeFlow = exchangeFlow
	p.ExchangeFlag = exchangeFlag
	p.VipRange = vipRange
	p.OtherParams = otherParam
	p.VerifyCodeType = verifyCodeType
	p.RegisterVerifyCodeSwitch = registerVerifyCodeSwitch
	p.ThirdGameMerchant = thirdState
	//p.NeedDeviceInfo = needDeviceInfo
	p.NeedSameName = needSameName
	p.PerBankNoLimitName = PerBankNoLimitName
	p.ExchangeGiveFlow = exchangeGiveFlow
	p.ExchangeBankMax = exchangeBankMax
	p.ExchangeAlipayMax = exchangeAlipayMax
	p.DgHboConfig = dgHboCfg
	p.IsCanUserBindPromoter = isCanUserBindPromoter
	p.UserBindPromoterPrize = userBindPromoterPrize
	p.SpreadWinLose = spreadWinLose
	p.ExchangeMultiple = exchangeMultiple
	p.MerchantKey = merchantKey
	p.BindTelReward = bindTelReward
	if p.ExchangeFlag&ExchangeFlag_Flow == 0 { //修正下
		p.ExchangeFlow = 0
	}
	//if oldIsolated != isolated {
	//	pm.ChangeIsolated(name, isolated)
	//}
	if oldDisabled != disable {
		pm.ChangeDisabled(name, disable)
	}
	//if oldBindPromoter != isCanUserBindPromoter {
	//	pm.ChangeIsCanBindPromoter(name, isCanUserBindPromoter)
	//}
	if ccf != nil {
		p.ClubConfig = ccf
	}
	return p
}

// Get 获取平台相关配置，不会返回nil
func (pm *PlatformMgr) Get(plt string) *PlatformConfig {
	cfg, ok := pm.configs[plt]
	if !ok {
		cfg = new(PlatformConfig)
		pm.configs[plt] = cfg
	}
	return cfg
}

func (this *PlatformMgr) UpdateConfig(config any) {
	if config == nil {
		return
	}
	switch v := config.(type) {
	case *webapiproto.PlayerPool:
		this.Get(v.GetPlatform()).PlayerPool = v
	default:
		logger.Logger.Errorf("unknown config type:%v", config)
	}
}

func (pm *PlatformMgr) UpdateEntrySwitch(config *webapiproto.EntrySwitch) {
	if config == nil {
		return
	}
	pm.Get(config.Platform).EntrySwitch = config
}

func (pm *PlatformMgr) GetEntrySwitch(plt string) *webapiproto.EntrySwitch {
	return pm.Get(plt).EntrySwitch
}

func (pm *PlatformMgr) UpdateCommonNotices(config *webapiproto.CommonNoticeList) {
	if config == nil {
		return
	}
	pm.Get(config.Platform).CommonNotices = config
}

func (pm *PlatformMgr) GetCommonNotices(plt string) *webapiproto.CommonNoticeList {
	return pm.Get(plt).CommonNotices
}

func (pm *PlatformMgr) SyncGameFree(platform string, data *webapiproto.GameFree) {
	packSgf := &loginproto.SCSyncGameFree{}
	gc := &loginproto.GameConfig{
		GameId:         proto.Int32(data.DbGameFree.GetGameId()),
		GameMode:       proto.Int32(data.DbGameFree.GetGameMode()),
		LogicId:        proto.Int32(data.DbGameFree.GetId()),
		State:          proto.Bool(data.Status),
		LimitCoin:      proto.Int64(data.DbGameFree.GetLimitCoin()),
		MaxCoinLimit:   proto.Int64(data.DbGameFree.GetMaxCoinLimit()),
		BaseScore:      proto.Int32(data.DbGameFree.GetBaseScore()),
		BetScore:       proto.Int32(data.DbGameFree.GetBetLimit()),
		OtherIntParams: data.DbGameFree.GetOtherIntParams(),
		MaxBetCoin:     data.DbGameFree.GetMaxBetCoin(),
		MatchMode:      proto.Int32(data.DbGameFree.GetMatchMode()),
	}
	if data.DbGameFree.GetLottery() != 0 {
		gc.LotteryCfg = data.DbGameFree.LotteryConfig
	}
	packSgf.Data = append(packSgf.Data, gc)
	if len(packSgf.Data) > 0 {
		PlayerMgrSington.BroadcastMessageToPlatform(platform, int(loginproto.LoginPacketID_PACKET_SC_SYNCGAMEFREE), packSgf)
	}
}

// UpsertGameFree 更新场次配置
func (pm *PlatformMgr) UpsertGameFree(platform string, data *webapiproto.GameFree) {
	p := pm.GetPlatform(platform)
	if p != nil {
		pgc := p.PltGameCfg
		if pgc != nil {
			dbGameFree := srvdata.PBDB_GameFreeMgr.GetData(data.DbGameFree.Id)
			if dbGameFree == nil {
				return
			}
			if data.GetDbGameFree() == nil { //数据容错
				data.DbGameFree = dbGameFree
			} else {
				CopyDBGameFreeField(dbGameFree, data.DbGameFree)
			}

			old, ok := pgc.games[data.DbGameFree.Id]
			pgc.games[data.DbGameFree.Id] = data
			found := false
			if ok && old != nil {
				if c, ok := pgc.cache[data.DbGameFree.Id]; ok {
					for i := 0; i < len(c); i++ {
						if c[i].DbGameFree.Id == data.DbGameFree.Id {
							c[i] = data
							found = true
							break
						}
					}
				}
			}
			if !found {
				pgc.cache[data.DbGameFree.Id] = append(pgc.cache[data.DbGameFree.Id], data)
			}
			if ok && old != nil && !CompareGameFreeConfigChged(old, data) {
				pm.OnPlatformGameFreeUpdate(p, old, data)
				pm.SyncGameFree(p.IdStr, data)
			}
		}
	}
}

func (pm *PlatformMgr) OnPlatformCreate(p *Platform) {
	for _, observer := range pm.Observers {
		observer.OnPlatformCreate(p)
	}
}

func (pm *PlatformMgr) OnPlatformGameFreeUpdate(p *Platform, oldCfg, newCfg *webapiproto.GameFree) {
	for _, observer := range pm.Observers {
		observer.OnPlatformGameFreeUpdate(p, oldCfg, newCfg)
	}
}

func (pm *PlatformMgr) OnPlatformDestroyByGameFreeId(p *Platform, gameFreeId int32) {
	for _, observer := range pm.Observers {
		observer.OnPlatformDestroyByGameFreeId(p, gameFreeId)
	}
}

func (pm *PlatformMgr) OnPlatformChangeDisabled(p *Platform, disable bool) {
	for _, observer := range pm.Observers {
		observer.OnPlatformChangeDisabled(p, disable)
	}
}

func (pm *PlatformMgr) ChangeDisabled(name string, disable bool) {
	if p := pm.GetPlatform(name); p != nil {
		if p.ChangeDisabled(disable) {
			pm.OnPlatformChangeDisabled(p, disable)
		}
	}
}

func (pm *PlatformMgr) GetPlatform(platform string) *Platform {
	return pm.Get(platform).Platform
}

func (pm *PlatformMgr) OnChangeSceneState(scene *Scene, startclose bool) {

}
func (pm *PlatformMgr) PlayerLogin(p *Player) {
	if p.IsRob {
		return
	}
	platform := pm.GetPlatform(p.Platform)
	if platform != nil {
		platform.PlayerLogin(p)
	}
}

func (pm *PlatformMgr) Broadcast(packetid int, packet interface{}, players map[int32]*Player, exclude int32) {
	mgs := make(map[*netlib.Session][]*srvlibproto.MCSessionUnion)
	for _, p := range players {
		if p != nil && p.gateSess != nil && p.IsOnLine() && exclude != p.SnId {
			mgs[p.gateSess] = append(mgs[p.gateSess], &srvlibproto.MCSessionUnion{
				Mccs: &srvlibproto.MCClientSession{
					SId: p.sid,
				},
			})
		}
	}
	for gateSess, v := range mgs {
		if gateSess != nil && len(v) != 0 {
			pack, err := MulticastMaker.CreateMulticastPacket(packetid, packet, v...)
			if err == nil {
				gateSess.Send(int(srvlibproto.SrvlibPacketID_PACKET_SS_MULTICAST), pack)
			}
		}
	}
}

func (pm *PlatformMgr) PlayerLogout(p *Player) {
	platform := pm.GetPlatform(p.Platform)
	if platform != nil && platform.Isolated {
		platform.PlayerLogout(p)
	} else {

	}
}

func (this *PlatformMgr) GetPackageTag(tag string) *webapiproto.AppInfo {
	logger.Logger.Tracef("Get %v platform.", tag)
	if pt, ok := this.PackageList[tag]; ok {
		return pt
	}
	return nil
}

func (this *PlatformMgr) GetPlatformByPackageTag(tag string) (int32, int32, int32, int32, int32) {
	logger.Logger.Tracef("Get %v platform.", tag)
	if pt, ok := this.PackageList[tag]; ok {
		return pt.PlatformId, 0, 0, 0, 0
	} else {
		return int32(DefaultPlatformInt), 0, 0, 0, 0
	}
}

func (this *PlatformMgr) GetCurrencyByPackageTag(tag string) (string, int32) {
	logger.Logger.Tracef("Get %v CurrencyRatio.", tag)
	if pt, ok := this.PackageList[tag]; ok && pt.CurrencyType != "" && pt.CurrencyRatio != 0 {
		return pt.CurrencyType, pt.CurrencyRatio
	}
	return "USD", 1
}

func (this *PlatformMgr) GetPlatformUpgradeAccountGiveCoinByPackageTag(tag string) int32 {
	platform, _, _, _, _ := this.GetPlatformByPackageTag(tag)
	return this.GetPlatformUpgradeAccountGiveCoinByPlatform(strconv.Itoa(int(platform)))
}

func (this *PlatformMgr) GetPlatformUpgradeAccountGiveCoinByPlatform(platform string) int32 {
	platformData := this.GetPlatform(platform)
	if platformData == nil {
		return 0
	}
	return platformData.UpgradeAccountGiveCoin
}

func (this *PlatformMgr) GetGameFrees(platform string) map[int32]*webapiproto.GameFree {
	p := this.GetPlatform(platform)
	if p == nil {
		return nil
	}

	data := make(map[int32]*webapiproto.GameFree)
	for id, val := range p.PltGameCfg.games {
		if !val.Status || !this.GameStatus[id] {
			continue
		}

		if val.GroupId != 0 {
			cfg := PlatformGameGroupMgrSington.GetGameGroup(val.GroupId)
			if cfg != nil {
				temp := &webapiproto.GameFree{
					GroupId:    cfg.GetId(),
					Status:     val.Status,
					DbGameFree: cfg.GetDbGameFree(),
				}
				data[id] = temp
			}
		} else {
			data[id] = val
		}
	}
	return data
}

func (this *PlatformMgr) GetGameFree(platform string, gameFreeId int32) *webapiproto.GameFree {
	p := this.GetPlatform(platform)
	if p == nil {
		return nil
	}

	gf := p.PltGameCfg.GetGameCfg(gameFreeId)
	if gf == nil {
		return nil
	}

	if !this.GameStatus[gameFreeId] || !gf.GetStatus() {
		return nil
	}

	return gf
}

// CheckGameState 场次开关状态
func (this *PlatformMgr) CheckGameState(platform string, gameFreeId int32) bool {
	gf := this.GetGameFree(platform, gameFreeId)
	if gf == nil {
		return false
	}
	return gf.Status
}

func (this *PlatformMgr) GetGameFreeGroup(platform string, gameFreeId int32) int32 {
	c := this.GetGameFree(platform, gameFreeId)
	if c != nil {
		return c.GroupId
	}
	return 0
}

func (this *PlatformMgr) GetCommonNotice(plt string) *webapiproto.CommonNoticeList {
	logger.Logger.Tracef("GetCommonNotice %v platform.", plt)
	if cfg := this.GetCommonNotices(plt); cfg != nil {
		//now := time.Now().Unix()
		re := &webapiproto.CommonNoticeList{
			Platform: cfg.Platform,
			List:     cfg.List,
		}
		//for _, v := range pt.List {
		//	if v.GetEndTime() > now && v.GetStartTime() < now {
		//		re.List = append(re.List, v)
		//	}
		//}
		return re
	}
	return nil
}

// ChangeGameStatus 后台切换超管游戏开关
func (this *PlatformMgr) ChangeGameStatus(cfgs []*hallproto.GameConfig1) {
	//向所有玩家发送状态变化协议
	pack := &hallproto.SCChangeGameStatus{}

	for _, p := range this.GetPlatforms() {
		for _, cfg := range cfgs {
			gameFreeId := cfg.LogicId
			data, ok := p.PltGameCfg.games[gameFreeId]
			if data != nil && ok && data.Status { //自身有这个游戏，且处于开启状态
				if !cfg.Status { //全局关，销毁游戏
					pack.GameCfg = append(pack.GameCfg, cfg)
					this.OnPlatformDestroyByGameFreeId(p, gameFreeId)
				} else {
					lgc := &hallproto.GameConfig1{
						LogicId:        proto.Int32(data.DbGameFree.Id),
						LimitCoin:      proto.Int64(data.DbGameFree.GetLimitCoin()),
						MaxCoinLimit:   proto.Int64(data.DbGameFree.GetMaxCoinLimit()),
						BaseScore:      proto.Int32(data.DbGameFree.GetBaseScore()),
						BetScore:       proto.Int32(data.DbGameFree.GetBetLimit()),
						OtherIntParams: data.DbGameFree.GetOtherIntParams(),
						MaxBetCoin:     data.DbGameFree.GetMaxBetCoin(),
						MatchMode:      proto.Int32(data.DbGameFree.GetMatchMode()),
						Status:         data.Status,
					}
					if data.DbGameFree.GetLottery() != 0 { //彩金池
						//lgc.LotteryCfg = data.DBGameFree.LotteryConfig
						//_, gl := LotteryMgrSington.FetchLottery(plf, data.DBGameFree.GetId(), data.DBGameFree.GetGameId())
						//if gl != nil {
						//	lgc.LotteryCoin = proto.Int64(gl.Value)
						//}
					}
					pack.GameCfg = append(pack.GameCfg, lgc)
				}
			}
		}

		if len(pack.GameCfg) > 0 {
			PlayerMgrSington.BroadcastMessageToPlatform(p.IdStr, int(hallproto.GameHallPacketID_PACKET_SC_CHANGEGAMESTATUS), pack)
		}
	}
}

// ChangeEntrySwitch 修改客户端游戏入口状态
func (this *PlatformMgr) ChangeEntrySwitch(platform string, cfg *webapiproto.EntrySwitch) {
	p := PlatformMgrSingleton.GetPlatform(platform)
	if p == nil {
		return
	}
	pack := &hallproto.SCChangeEntrySwitch{}

	for _, v := range cfg.GetDatas() {
		pack.GameCfg = append(pack.GameCfg, v)
	}

	PlayerMgrSington.BroadcastMessageToPlatform(platform, int(hallproto.GameHallPacketID_PACKET_SC_CHANGEENTRYSWITCH), pack)
}

func (this *PlatformMgr) ModuleName() string {
	return "PlatformMgr"
}

func (this *PlatformMgr) Init() {

}

func (this *PlatformMgr) LoadPlatform() {
	//构建默认的平台数据
	this.CreateDefaultPlatform()
	//获取平台数据 platform_list

	//不使用etcd的情况下走api获取
	if !model.GameParamData.UseEtcd {
		//buf, err := webapi.API_GetPlatformData(common.GetAppId())
		//if err == nil {
		//	ar := webapi_proto.ASPlatformInfo{}
		//	err = proto.Unmarshal(buf, &ar)
		//	if err == nil && ar.Tag == webapi_proto.TagCode_SUCCESS {
		//		for _, value := range ar.Platforms {
		//			platform := this.CreatePlatform(value.Id, value.Isolated)
		//			platform.Name = value.PlatformName
		//			//platform.ConfigId = value.ConfigId
		//			platform.Disable = value.Disabled
		//			platform.ServiceUrl = value.CustomService
		//			platform.CustomType = value.CustomType
		//			platform.BindOption = value.BindOption
		//			//platform.ServiceFlag = value.ServiceFlag
		//			platform.UpgradeAccountGiveCoin = value.UpgradeAccountGiveCoin
		//			platform.NewAccountGiveCoin = value.NewAccountGiveCoin       //新账号奖励金币
		//			platform.PerBankNoLimitAccount = value.PerBankNoLimitAccount //同一银行卡号绑定用户数量限制
		//			platform.ExchangeMin = value.ExchangeMin
		//			platform.ExchangeLimit = value.ExchangeLimit
		//			platform.ExchangeTax = value.ExchangeTax
		//			platform.ExchangeFlow = value.ExchangeFlow
		//			platform.ExchangeVer = value.ExchangeVer
		//			platform.ExchangeFlag = value.ExchangeFlag
		//			platform.ExchangeForceTax = value.ExchangeForceTax
		//			platform.ExchangeGiveFlow = value.ExchangeGiveFlow
		//			platform.VipRange = value.VipRange
		//			//platform.OtherParams = value.OtherParams
		//			platform.SpreadConfig = value.SpreadConfig
		//			//platform.RankSwitch = value.Leaderboard
		//			//platform.ClubConfig = value.ClubConfig
		//			platform.VerifyCodeType = value.VerifyCodeType
		//			//platform.RegisterVerifyCodeSwitch = value.RegisterVerifyCodeSwitch
		//			for _, v := range value.ThirdGameMerchant {
		//				platform.ThirdGameMerchant[v.Id] = v.Merchant
		//			}
		//			//platform.NeedDeviceInfo = value.NeedDeviceInfo
		//			platform.NeedSameName = value.NeedSameName
		//			platform.PerBankNoLimitName = value.PerBankNoLimitName
		//			platform.ExchangeAlipayMax = value.ExchangeAlipayMax
		//			platform.ExchangeBankMax = value.ExchangeBankMax
		//			//platform.DgHboConfig = value.DgHboConfig
		//			platform.IsCanUserBindPromoter = value.IsCanUserBindPromoter
		//			platform.UserBindPromoterPrize = value.UserBindPromoterPrize
		//			//platform.SpreadWinLose = value.SpreadWinLose
		//			platform.ExchangeMultiple = value.ExchangeMultiple
		//			if platform.ExchangeFlag&ExchangeFlag_Flow == 0 { //修正下
		//				platform.ExchangeFlow = 0
		//			}
		//			platform.MerchantKey = value.MerchantKey
		//		}
		//		logger.Logger.Trace("Create platform")
		//	} else {
		//		logger.Logger.Error("Unmarshal platform data error:", err)
		//	}
		//} else {
		//	logger.Logger.Error("Get platfrom data error:", err)
		//}
	} else {
		EtcdMgrSington.InitPlatform()
	}
}

func (this *PlatformMgr) LoadPlatformGameFree() {
	//不使用etcd的情况下走api获取

	//获取平台详细信息 game_config_list
	if !model.GameParamData.UseEtcd {
		//logger.Logger.Trace("API_GetPlatformConfigData")
		//buf, err := webapi.API_GetPlatformConfigData(common.GetAppId())
		//if err == nil {
		//	pcdr := &webapi_proto.ASGameConfig{}
		//	err = proto.Unmarshal(buf, pcdr)
		//	if err == nil && pcdr.Tag == webapi_proto.TagCode_SUCCESS {
		//		platGameCfgs := pcdr.GetConfigs()
		//
		//		//遍历所有平台配置
		//		for _, pgc := range platGameCfgs {
		//			platormId := pgc.GetPlatformId()
		//			platform := this.GetPlatform(strconv.Itoa(int(platormId)))
		//			if platform == nil {
		//				continue
		//			}
		//
		//			for _, config := range pgc.GetDbGameFrees() {
		//				dbGameFree := srvdata.PBDB_GameFreeMgr.GetData(config.DbGameFree.Id)
		//				if dbGameFree == nil {
		//					logger.Logger.Error("Platform config data error logic id:", config)
		//					continue
		//				}
		//				platform.PltGameCfg.games[config.DbGameFree.Id] = config
		//				if config.GetDbGameFree() == nil { //数据容错
		//					config.DbGameFree = dbGameFree
		//				} else {
		//					CopyDBGameFreeField(dbGameFree, config.DbGameFree)
		//				}
		//				logger.Logger.Info("PlatformGameConfig data:", config.DbGameFree.Id)
		//			}
		//			platform.PltGameCfg.RecreateCache()
		//		}
		//	} else {
		//		logger.Logger.Error("Unmarshal platform config data error:", err, string(buf))
		//	}
		//} else {
		//	logger.Logger.Error("Get platfrom config data error:", err)
		//}
	} else {
		EtcdMgrSington.InitPlatformGameConfig()
	}
}

func (this *PlatformMgr) LoadPlatformPackage() {
	if !model.GameParamData.UseEtcd {

	} else {
		EtcdMgrSington.InitPlatformPackage()
	}
}

func (this *PlatformMgr) LoadCommonNotice() {
	if !model.GameParamData.UseEtcd {

	} else {
		EtcdMgrSington.InitCommonNotice()
	}
}

func (this *PlatformMgr) LoadGameMatch() {
	if !model.GameParamData.UseEtcd {

	} else {
		EtcdMgrSington.InitGameMatchDate()
	}
}

// LoadGlobalGameStatus 加载超管平台游戏开关
func (this *PlatformMgr) LoadGlobalGameStatus() {
	//不使用etcd的情况下走api获取
	if !model.GameParamData.UseEtcd {
		////获取全局游戏开关
		//logger.Logger.Trace("API_GetGlobalGameStatus")
		//buf, err := webapi.API_GetGlobalGameStatus(common.GetAppId())
		//if err == nil {
		//	as := webapi_proto.ASGameConfigGlobal{}
		//	err = proto.Unmarshal(buf, &as)
		//	if err == nil && as.Tag == webapi_proto.TagCode_SUCCESS {
		//		if as.GetGameStatus() != nil {
		//			status := as.GetGameStatus().GetGameStatus()
		//			for _, v := range status {
		//				gameId := v.GetGameId()
		//				status := v.GetStatus()
		//				PlatformMgrSingleton.GameStatus[gameId] = status
		//			}
		//		}
		//	} else {
		//		logger.Logger.Error("Unmarshal GlobalGameStatus data error:", err)
		//	}
		//} else {
		//	logger.Logger.Error("Get GlobalGameStatus data error:", err)
		//}
	} else {
		EtcdMgrSington.InitGameGlobalStatus()
	}
}

// LoadEntrySwitch 拉取界面入口开关
func (this *PlatformMgr) LoadEntrySwitch() {
	//不使用etcd的情况下走api获取
	if model.GameParamData.UseEtcd {
		EtcdMgrSington.InitEntrySwitch()
	} else {

	}
}

func (this *PlatformMgr) Update() {

}

func (this *PlatformMgr) Shutdown() {
	module.UnregisteModule(this)
}

func (this *PlatformMgr) InterestClockEvent() int {
	return 1<<CLOCK_EVENT_HOUR | 1<<CLOCK_EVENT_DAY
}

func (this *PlatformMgr) OnDayTimer() {
	for _, platform := range this.GetPlatforms() {
		utils.CatchPanic(func() {
			platform.OnDayTimer()
		})
	}
}

func (this *PlatformMgr) OnHourTimer() {
	for _, platform := range this.GetPlatforms() {
		utils.CatchPanic(func() {
			platform.OnHourTimer()
		})
	}
}

// CopyDBGameFreeField 需要使用本地配置的属性
// src 本地场次配置
// dst 后台场次配置
func CopyDBGameFreeField(src, dst *serverproto.DB_GameFree) {
	dst.Id = src.Id
	dst.Name = src.Name
	dst.Title = src.Title
	dst.ShowType = src.ShowType
	dst.SubShowType = src.SubShowType
	dst.Flag = src.Flag
	dst.GameRule = src.GameRule
	dst.TestTakeCoin = src.TestTakeCoin
	dst.SceneType = src.SceneType
	dst.GameType = src.GameType
	dst.GameId = src.GameId
	dst.GameMode = src.GameMode
	dst.ShowId = src.ShowId
	dst.ServiceFee = src.ServiceFee
	dst.Turn = src.Turn
	dst.BetDec = src.BetDec
	//dst.CorrectNum = src.CorrectNum
	//dst.CorrectRate = src.CorrectRate
	//dst.Deviation = src.Deviation
	//dst.Ready = src.Ready
	dst.Ai = src.Ai
	dst.Jackpot = src.Jackpot
	//dst.ElementsParams = src.ElementsParams
	//dst.OtherElementsParams = src.OtherElementsParams
	//dst.DownRiceParams = src.DownRiceParams
	//dst.InitValue = src.InitValue
	//dst.LowerLimit = src.LowerLimit
	//dst.UpperLimit = src.UpperLimit
	//dst.UpperOffsetLimit = src.UpperOffsetLimit
	//dst.MaxOutValue = src.MaxOutValue
	//dst.ChangeRate = src.ChangeRate
	//dst.MinOutPlayerNum = src.MinOutPlayerNum
	//dst.UpperLimitOfOdds = src.UpperLimitOfOdds
	if len(dst.RobotNumRng) < 2 {
		dst.RobotNumRng = src.RobotNumRng
	}
	//dst.SameIpLimit = src.SameIpLimit
	//dst.BaseRate = src.BaseRate
	//dst.CtroRate = src.CtroRate
	//dst.HardTimeMin = src.HardTimeMin
	//dst.HardTimeMax = src.HardTimeMax
	//dst.NormalTimeMin = src.NormalTimeMin
	//dst.NormalTimeMax = src.NormalTimeMax
	//dst.EasyTimeMin = src.EasyTimeMin
	//dst.EasyTimeMax = src.EasyTimeMax
	//dst.EasrierTimeMin = src.EasrierTimeMin
	//dst.EasrierTimeMax = src.EasrierTimeMax
	dst.GameType = src.GameType
	dst.GameDif = src.GameDif
	dst.GameClass = src.GameClass
	dst.PlatformName = src.PlatformName
	if len(dst.MaxBetCoin) == 0 {
		dst.MaxBetCoin = src.MaxBetCoin
	}

	//预创建房间数量走后台配置
	//dst.CreateRoomNum = src.CreateRoomNum
	//后台功能做上后，优先使用后台的配置，默认直接用表格种配好的
	//if !model.GameParamData.MatchTrueManUseWeb {
	//	dst.MatchTrueMan = src.MatchTrueMan
	//}

	////默认走本地配置
	//if dst.PlayerWaterRate == nil {
	//	tv := src.GetPlayerWaterRate()
	//	dst.PlayerWaterRate = &tv
	//}
	//
	//if dst.BetWaterRate == nil {
	//	tv := src.GetBetWaterRate()
	//	dst.BetWaterRate = &tv
	//}

}

func init() {
	ClockMgrSington.RegisteSinker(PlatformMgrSingleton)
	module.RegisteModule(PlatformMgrSingleton, time.Second*2, 0)

	RegisterParallelLoadFunc("拉取平台数据", func() error {
		PlatformMgrSingleton.LoadPlatform()
		return nil
	})

	RegisterParallelLoadFunc("拉取平台游戏开关", func() error {
		PlatformMgrSingleton.LoadGlobalGameStatus()
		return nil
	})

	RegisterParallelLoadFunc("拉取游戏入口开关", func() error {
		PlatformMgrSingleton.LoadEntrySwitch()
		return nil
	})

	RegisterParallelLoadFunc("拉取平台游戏详细配置", func() error {
		PlatformMgrSingleton.LoadPlatformGameFree()
		return nil
	})

	RegisterParallelLoadFunc("平台包数据", func() error {
		PlatformMgrSingleton.LoadPlatformPackage()
		return nil
	})

	RegisterParallelLoadFunc("平台公告", func() error {
		PlatformMgrSingleton.LoadCommonNotice()
		return nil
	})

	RegisterParallelLoadFunc("平台比赛", func() error {
		PlatformMgrSingleton.LoadGameMatch()
		return nil
	})
}
