package mergeCluster

import (
	"fmt"
	"server/GoUtil"
	"server/conf"
	"server/game/mod/msg"
	"server/pkg/github.com/name5566/leaf/log"
	"server/pkg/github.com/name5566/leaf/network"
	"time"
)

func RevcServerMsg(m *msg.Msg) error {
	log.Debug("RevcServerMsg m %v", m)
	return nil
}

// 连接成功 之后同步区服信息
func HandShake(a *Agent) {
	m := &msg.Msg{
		Type:  msg.CLUSTER_HANDSHAKE_1,
		From:  conf.Server.ServerID,
		Extra: conf.Server.RemoteAddr,
	}
	data, err := GoUtil.GobMarshal(m)
	if err != nil {
		log.Debug("HandShake GobMarshal err %v", err)
		return
	}
	// log.Debug("握手 server id :%d", conf.Server.ServerID)
	a.WriteMsg(data)
}

// 握手回调
func HandShakeRecv(a *Agent, m *msg.Msg) error {
	ServerId := m.From
	// log.Debug("收到握手回复 ServerId %v", ServerId)
	a.ServerId = ServerId
	serverAgent.Store(ServerId, a)

	if conf.Server.ServerID == ClusterCenterId {
		log.Debug("通知区服：%d加入网路", m.From)
		SendMsgAll(&msg.Msg{
			Type: msg.CLUSTER_JOIN,
			From: conf.Server.ServerID,
			Extra: &ClusterJoinData{
				ServerId:   m.From,
				RemoteAddr: m.Extra.(string),
			},
		})
	}
	syncMsg := &msg.Msg{
		Type: msg.CLUSTER_FRIEND_SYNC,
		To:   ServerId,
	}
	sendGameMsg(syncMsg)
	// fmt.Print("现有区服连接：")
	// serverAgent.Range(func(key, value interface{}) bool {
	// 	fmt.Print(key)
	// 	fmt.Print(",")
	// 	return true
	// })
	// fmt.Println()
	return nil
}

func HandShakeRecv2(a *Agent, m *msg.Msg) error {
	ServerId := m.From
	a.ServerId = ServerId
	log.Debug("HandShakeRecv2 ServerId %v", ServerId)
	serverAgent.Store(ServerId, a)
	return nil
}

func ClusterJoin(a *Agent, m *msg.Msg) error {
	clusterJoin := m.Extra.(*ClusterJoinData)
	if conf.Server.ServerID == clusterJoin.ServerId {
		log.Debug("区服加入通知为本服， 不处理")
		return nil
	}
	log.Debug("ClusterJoin ServerId %v", clusterJoin.ServerId)
	connectRemote(clusterJoin.RemoteAddr, clusterJoin.ServerId, "server")
	return nil
}

func ClusterExit(a *Agent, m *msg.Msg) error {
	clusterExit := m.Extra.(*ClusterExitData)
	if conf.Server.ServerID == clusterExit.ServerId {
		return nil
	}
	serverAgent.Delete(clusterExit.ServerId)
	return nil
}

func connectRemote(RemoteAddr string, ConnType int, ConnLabel string) error {
	client := new(network.TCPClient)
	client.Addr = RemoteAddr
	client.ConnNum = 1
	client.PendingWriteNum = conf.PendingWriteNum
	client.LenMsgLen = 4
	client.MaxMsgLen = 4096
	client.NewAgent = newAgent
	client.ConnType = ConnType
	client.ConnLabel = ConnLabel
	client.ConnectInterval = time.Duration(time.Minute * 5)
	if ConnType == ClusterCenterId { // 中心服断开重连
		client.AutoReconnect = true
	}
	client.Start()
	Center = client
	clients = append(clients, client)
	return nil
}

func SendServerMsg(m *msg.Msg, serverId int) error {
	if v, ok := serverAgent.Load(serverId); ok {
		data, err := GoUtil.GobMarshal(m)
		if err != nil {
			log.Debug("SendServerMsg GobMarshal err %v", err)
			return err
		}
		v.(network.Agent).WriteMsg(data)
		return nil
	}
	return fmt.Errorf("server %d not online", serverId)
}

func SendMsgAll(m *msg.Msg) {
	data, err := GoUtil.GobMarshal(m)
	if err != nil {
		log.Debug("SendMsgAll GobMarshal err %v", err)
		return
	}
	serverAgent.Range(func(key, value interface{}) bool {
		value.(network.Agent).WriteMsg(data)
		return true
	})
}

func processMsg(a *Agent, m *msg.Msg) error {
	var err error
	if fun, ok := FuncMap[m.Type]; ok {
		err = fun(a, m)
	} else {
		MsgChan <- m //交由game Module消息处理
	}
	return err
}

func registerFunc(key int, fun func(*Agent, *msg.Msg) error) {
	FuncMap[key] = fun
}

func sendGameMsg(m *msg.Msg) {
	MsgChan <- m
}
