package internal

import (
	"leaf/gate"
	"leaf/log"
	"reflect"
	"server/src/conf"
	"server/src/internal/data"
	"server/src/internal/user"
	"server/src/msg"
	"time"
)

func init() {
	// 心跳检测
	go checkHeartbeat()

	/***************************** 向当前模块（game 模块）注册 相关消息处理函数 *****************************/
	handler(&msg.CS_Heartbeat{}, onHeartbeat)
	handler(&msg.CS_User_Login{}, onUserLogin)

	//client, err := mongoPool.GetClient(false)
	//if err != nil {
	//
	//}
}

// 回调注册
func handler(m interface{}, h interface{}) {
	skeleton.RegisterChanRPC(reflect.TypeOf(m), h)
}

func checkHeartbeat() {
	// 定时执行心跳检测
	ticker := time.NewTicker(conf.HeartbeatCheckTime)
	defer ticker.Stop()

	for {
		select {
		case <-ticker.C:
			now := time.Now().Unix()
			//logout := []gate.Agent{}

			// 遍历所有连接
			for a, _ := range agents {
				// 客户端登录成功才回构建agent中的userdata
				if a.UserData() != nil {
					userData := a.UserData().(data.AgentData)
					diff := time.Duration(now-userData.ActiveTime) * time.Second
					if diff >= conf.HeartbeatTimeout {
						// 超时踢出
						sendMsg(a, msg.HEART, msg.SC_KICK_TIMEOUT, &msg.SC_KickByTimeout{})
						log.Debug("send userid = %s 心跳超时,关闭连接", userData.UserId)
						// 关闭连接
						a.Close()
						// 清理在线用户数据
						user.GetUserSystem().UnRegister(userData.UserId)
						delete(agents, a)
					} else {
						//log.Debug("心跳正常")
					}
				}
			}
		}
	}
}

// 发消息到客户端
func sendMsg(a gate.Agent, mainCmd, subCmd uint8, msg interface{}) {
	if a == nil {
		log.Debug("data is nil")
		return
	}
	// 更新心跳检测时间
	userData := a.UserData().(data.AgentData)
	userData.ActiveTime = time.Now().Unix()
	a.SetUserData(userData)

	// 发送消息
	a.WriteMsgByMsgID(mainCmd, subCmd, msg)
}

// 心跳回调
func onHeartbeat(args []interface{}) {
	// 收到的 CS_Heartbeat 消息
	//m := args[0].(*msg.CS_Heartbeat)
	// 消息的发送者
	a := args[1].(gate.Agent)

	// 输出收到的消息的内容
	log.Debug("recv CS_Heartbeat")

	// 回应
	//a.WriteMsgByMsgID(msg.HEART, msg.SC_RESPONSE, &msg.SC_Heartbeat{})
	sendMsg(a, msg.HEART, msg.SC_RESPONSE, &msg.SC_Heartbeat{})

	// test
	//time.Sleep(10 * time.Second)
	//log.Debug("test disconnect")
	//a.Close()

	// 测试遍历
	for a := range agents {
		log.Debug("recv onHeartbeat agent user id = %s, time = %d", a.UserData().(data.AgentData).UserId, a.UserData().(data.AgentData).ActiveTime)
	}

}

// 玩家登陆游戏回调
func onUserLogin(args []interface{}) {
	// 收到的 CS_User_Login 消息
	m := args[0].(*msg.CS_User_Login)
	// 消息的发送者
	a := args[1].(gate.Agent)

	// 输出收到的消息的内容
	log.Debug("recv CS_User_Login udid = %s", m.GetUdid())

	// 登录成功用户信息保存到缓存和agent中
	userId := "test01"
	newUser := user.User{
		UserId:   "test01",
		NickName: "UserId",
		Token:    "Token",
	}
	user.GetUserSystem().Register(userId, &newUser)
	// agent user data: userid + activetime(心跳检测用)
	a.SetUserData(data.AgentData{UserId: userId, ActiveTime: time.Now().Unix()})

	// 回应
	//a.WriteMsgByMsgID(msg.USER, msg.SC_LOGIN, &msg.SC_User_Login{
	sendMsg(a, msg.HEART, msg.SC_RESPONSE, &msg.SC_User_Login{
		Err:        0,
		Udid:       m.GetUdid(),
		UserID:     1,
		ServerTime: time.Now().Unix(),
	})
}
