package network

import (
	_ "World/conf"
	"World/pb"
	"common/logger"
	_ "errors"
	"net"
	"reflect"

	"github.com/glog"
	"github.com/golang/protobuf/proto"
)

//type MessageHandler func(conn net.Conn, header pb.MessageHeader, msg proto.Message)

type MessageInfo struct {
	msgType    reflect.Type
	msgHandler reflect.Value
}

var (
	msg_map = make(map[uint16]*MessageInfo)
)

func MsgIDExist(msgid uint16) bool {
	if _, ok := msg_map[msgid]; ok {
		return true
	}
	return false
}

func RegisterMessage(msgid uint16, msg interface{}, handler interface{}) {
	_, ok := msg_map[msgid]
	if ok {
		glog.Warningf("消息[%v %v]重复注册", msgid, pb.MSGID(msgid).String())
		return
	}

	if reflect.TypeOf(handler).Kind() != reflect.Func {
		glog.Warningf("消息[%v %v]处理不是函数", msgid, pb.MSGID(msgid).String())
		return
	}

	if reflect.TypeOf(msg).Kind() != reflect.Struct {
		glog.Warningf("消息[%v %v]对应的消息体不是一个结构体", msgid, pb.MSGID(msgid).String())
		return
	}

	msg_map[msgid] = &MessageInfo{
		msgHandler: reflect.ValueOf(handler),
		msgType:    reflect.TypeOf(msg),
	}
}

func HandleRawData(conn net.Conn, header pb.MessageHeader, data []byte) {
	if info, ok := msg_map[header.MsgID]; ok {
		msg := reflect.New(info.msgType)
		err := proto.Unmarshal(data, msg.Interface().(proto.Message))
		if err != nil {
			return
		}
		info.msgHandler.Call([]reflect.Value{reflect.ValueOf(conn), reflect.ValueOf(header), msg})
		//info.msgHandler(conn, header, msg)
		return
	}
	logger.Notic("not regist msgid:%v from player:%v", header.MsgID, header.PlayerID)
}
