package main

import (
	"bytes"
	"mongo.games.com/game/common"
	"mongo.games.com/game/model"
	"mongo.games.com/game/proto"
	"mongo.games.com/game/protocol/rank"
	"mongo.games.com/game/protocol/server"
	"mongo.games.com/goserver/core/logger"
	"mongo.games.com/goserver/core/netlib"
	"mongo.games.com/goserver/srvlib"
)

func init() {
	netlib.RegisteUnknowPacketHandlerCreator("packetdispatchhandler", func() netlib.UnknowPacketHandler {
		return netlib.UnknowPacketHandlerWrapper(func(s *netlib.Session, packetid int, logicNo uint32, data []byte) bool {
			if !s.Auth {
				logger.Logger.Trace("packetdispatchhandler session not auth! ")
				return false
			}
			var ss *netlib.Session
			switch {
			case packetid >= 2000 && packetid < 5000:
				worldSess := s.GetAttribute(common.ClientSessionAttribute_WorldServer)
				if worldSess == nil {
					ss = srvlib.ServerSessionMgrSington.GetSession(common.GetSelfAreaId(), srvlib.WorldServerType, common.GetWorldSrvId())
					s.SetAttribute(common.ClientSessionAttribute_WorldServer, ss)
				} else {
					ss = worldSess.(*netlib.Session)
					if ss == nil {
						ss = srvlib.ServerSessionMgrSington.GetSession(common.GetSelfAreaId(), srvlib.WorldServerType, common.GetWorldSrvId())
						s.SetAttribute(common.ClientSessionAttribute_WorldServer, ss)
					}
				}

			case packetid >= 10000 && packetid < 12000:

				if rankSession == nil {
					logger.Logger.Trace("packetdispatchhandler redirect ranksrv is nil ", packetid)
					return true
				}

				buf := bytes.NewBuffer(nil)
				buf.Write(data)

				var pdi = s.GetAttribute(common.ClientSessionAttribute_PlayerData)
				if pdi == nil {
					logger.Logger.Trace("packetdispatchhandler redirect playerdata is nil ", packetid)
					return true
				}
				var playerData = pdi.(*model.PlayerData)

				gateTransmit := &rank.GateTransmit{
					Platform:   playerData.Platform,
					Snid:       playerData.GetSnId(),
					PacketData: buf.Bytes(),
				}

				b, err := netlib.MarshalPacket(packetid, gateTransmit)
				if err != nil {
					logger.Logger.Error("packetdispatchhandler redirect marshal error ", err)
					return true
				}

				pack := &server.SSTransmit{
					PacketData: b,
				}
				param := s.GetAttribute(srvlib.SessionAttributeClientSession)
				if param != nil {
					if sid, ok := param.(srvlib.SessionId); ok {
						pack.SessionId = proto.Int64(sid.Get())
					}
				}
				proto.SetDefaults(pack)
				rankSession.Send(int(server.TransmitPacketID_PACKET_SS_PACKET_TRANSMIT), pack)

				return true

			default:
				gameSess := s.GetAttribute(common.ClientSessionAttribute_GameServer)
				if gameSess == nil {
					logger.Logger.Trace("packetdispatchhandler not found fit gamesession! ", packetid)
					return true
				}
				ss = gameSess.(*netlib.Session)
			}

			if ss == nil {
				logger.Logger.Trace("packetdispatchhandler redirect server session is nil ", packetid)
				return true
			}
			//must copy
			buf := bytes.NewBuffer(nil)
			buf.Write(data)
			pack := &server.SSTransmit{
				PacketData: buf.Bytes(),
			}
			param := s.GetAttribute(srvlib.SessionAttributeClientSession)
			if param != nil {
				if sid, ok := param.(srvlib.SessionId); ok {
					pack.SessionId = proto.Int64(sid.Get())
				}
			}
			proto.SetDefaults(pack)
			ss.Send(int(server.TransmitPacketID_PACKET_SS_PACKET_TRANSMIT), pack)
			logger.Logger.Trace("transmit:", pack)
			return true
		})
	})
}
