package readcallsignal

import (
	"encoding/binary"
	"runtime/debug"

	"gitlab.com/cinnamon/voiceagent/icserror"
	"gitlab.com/cinnamon/voiceagent/icslog"
	"gitlab.com/cinnamon/voiceagent/recorddata"
)

type CallSignal struct {
	ChannelID  string
	ServerID   string
	AgentID    string
	Station    string
	CreateTime int64
	EventType  string
	StartTime  int64
	EndTime    int64
	InOut      string
	CustID     string
}

type CallSignalP struct {
	CallSignal [recorddata.MAX_CALLSIGNAL_PACKET_LEN]byte
}

//call signal protocol offset. ex)buffer[id:len]
const (
	CHANNELID      = 0              //byte array 13
	CHANNELID_LEN  = 13             //byte array 13
	SERVERID       = CHANNELID + 13 //short 2
	SERVERID_LEN   = SERVERID + 2   //short 2
	AGENTID        = SERVERID + 2   //byte array 16
	AGENTID_LEN    = AGENTID + 16   //byte array 16
	STATION        = AGENTID + 16   //int 4
	STATION_LEN    = STATION + 4    //int 4
	CREATETIME     = STATION + 4    //long 8
	CREATETIME_LEN = CREATETIME + 8 //long 8
	EVENTTYPE      = CREATETIME + 8 //byte 1
	EVENTTYPE_LEN  = EVENTTYPE + 1  //byte 1
	STARTTIME      = EVENTTYPE + 1  //long 8
	STARTTIME_LEN  = STARTTIME + 8  //long 8
	ENDTIME        = STARTTIME + 8  //long 8
	ENDTIME_LEN    = ENDTIME + 8    //long 8
	INOUT          = ENDTIME + 8    //byte 1
	INOUT_LEN      = INOUT + 1      //byte 1
	CUSTID         = INOUT + 1      //1
	CUSTID_LEN     = CUSTID + 20
)

func NewCallSignal(data []byte) *CallSignal {
	if len(data) > recorddata.MAX_CALLSIGNAL_PACKET_LEN {
		/*
			for iter, v := range data {
				fmt.Println(iter, v)
			}
			fmt.Printf("len>>>> %d, |%s|\n", len(data), string(data))
		*/
		return nil
	}

	cs := CallSignal{}
	cs.Parse(data)
	//fmt.Printf("%+v\n", cs)

	return &cs
}

func (cs *CallSignal) Parse(data []byte) *icserror.IcsError {
	l := icslog.GetIcsLog()
	var derr *icserror.IcsError = nil

	defer func() {
		if err := recover(); err != nil {
			switch v := err.(type) {
			case error:
				icserror.ICSERRRECORDDATAParsing.SetError(v)
				l.Printf(icslog.LOG_LEVEL_WARN, -1, "PANIC! %s\n%s", icserror.ICSERRRECORDDATAParsing.GetError().Error(), string(debug.Stack()))
			default:
				l.Print(icslog.LOG_LEVEL_WARN, -1, icserror.ICSERRRECORDDATAParsing.GetError().Error())
			}
		}
		derr = icserror.ICSERRRECORDDATAParsing
	}()

	cs.ChannelID = string(data[CHANNELID:CHANNELID_LEN])
	cs.ServerID = string(data[SERVERID:SERVERID_LEN])
	cs.AgentID = string(data[AGENTID:AGENTID_LEN])
	//istation := int(binary.LittleEndian.Uint32(data[STATION:STATION_LEN]))
	//cs.Station = fmt.Sprintf("%d", istation)
	//fmt.Println("Station", cs.Station)
	cs.Station = string(data[STATION:STATION_LEN])
	cs.CreateTime = int64(binary.LittleEndian.Uint64(data[CREATETIME:CREATETIME_LEN]))
	cs.EventType = string(data[EVENTTYPE:EVENTTYPE_LEN][0])
	cs.StartTime = int64(binary.LittleEndian.Uint64(data[STARTTIME:STARTTIME_LEN]))
	cs.EndTime = int64(binary.LittleEndian.Uint64(data[ENDTIME:ENDTIME_LEN]))

	//fmt.Printf("100LINE>>> %d\n", data[INOUT:INOUT_LEN][0])
	switch data[INOUT:INOUT_LEN][0] {
	case 254:
		cs.InOut = "10"
	case 255:
		cs.InOut = "11"
	default:
		cs.InOut = string(data[INOUT:INOUT_LEN][0])
	}

	cs.CustID = string(data[CUSTID:CUSTID_LEN])

	return derr
}