package logic

import (
	base "Server-Core/Server/Base"
	log "Server-Core/Server/Base/Log"
	service "Server-Core/Server/Base/Service"
	message "Server-Core/Server/Message"
	"sync"
	"time"
)

var G *LogicMgr

type LogicMgr struct {
	running bool
	ch      chan service.Msg
	wg      *sync.WaitGroup

	roomMng   *RoomMgr
	playerMng *PlayerMgr

	beginTick      int64 //服务器开启时间
	LastStatusTick int64 //上一次记录服务器状态的时间
}

func (mgr *LogicMgr) Init(ch chan service.Msg, wg *sync.WaitGroup, args ...interface{}) error {
	register()
	mgr.running = true
	mgr.ch = ch
	mgr.wg = wg

	mgr.roomMng = CreateRoomMgr()
	mgr.playerMng = CreatePlayerMgr()
	mgr.beginTick = time.Now().Unix()
	mgr.LastStatusTick = 0

	G = mgr

	return nil
}

func (mgr *LogicMgr) UnInit() {
	mgr.running = false
}

func (mgr *LogicMgr) Status() bool {
	return mgr.running
}

func (mgr *LogicMgr) Shutdown() {
	log.Info("logicMgr服务退出")
	mgr.running = false
	mgr.wg.Done()
}

func (mgr *LogicMgr) Run() {
	defer base.TryE()
	defer mgr.Shutdown()

	timer := time.After(time.Millisecond * 500) // timer
	for mgr.running {
		select {
		case <-timer:
			timer = time.After(time.Millisecond * 500) // timer
			mgr.roomMng.Run()                          //遍历房间
			now := time.Now().Unix()
			for _, player := range mgr.playerMng.playerByClientId {
				if now-player.LastHeartbeat > 30 {
					service.Send("clientMgr", "kick", player.ClientId, message.KickReason_KICK_REASON_HEARTBEAT_TIMEOUT)
					mgr.playerMng.RemovePlayer(player.PlayerId)
					//mgr.roomMng.RemovePlayer(player.PlayerId)
				} else {
					player.Run()
				}
			}
			//每过半个小时打印一次服务器上玩家和房间的总人数
			if now-mgr.LastStatusTick >= 1800 {
				log.Info("服务器人数:%d  房间数量:%d", len(mgr.playerMng.playerByClientId), len(mgr.roomMng.roomByRoomId))
				mgr.LastStatusTick = now
			}

		case msg, ok := <-mgr.ch:
			if !ok {
				continue
			}
			ok = true
			cmd := msg.Cmd
			if msg.Cmd == "clientCmd" {
				msgId := msg.Args[0].(int)
				cmd = string(msgId)
				handler, ok := clientCmd[message.MSGID(msgId)]
				if ok {
					handler(msg.Args[1].(int), msg.Args[2].([]byte))
				}
			} else {
				handler, ok := execute[msg.Cmd]
				if !ok {
					log.Error("未注册命令 cmd:%s", msg.Cmd)
					continue
				}
				if msg.Sync {
					msg.Done <- handler(msg.Args)
				} else {
					handler(msg.Args)
				}
			}
			if !ok {
				log.Error("未注册命令 cmd:%s", cmd)
				continue
			}
		}
	}
}
