package icsstat

import (
	"fmt"
	"io"

	"gitlab.com/ics_cinnamon/voiceStatistics/icsconf"
	"gitlab.com/ics_cinnamon/voiceStatistics/icserror"
	"gitlab.com/ics_cinnamon/voiceStatistics/icslog"
	"gitlab.com/ics_cinnamon/voiceStatistics/icsnet"
)

type StatInfos struct {
	//necessary value
	SeqId       string // 25
	LogTime     string // 14
	LogType     string // 3
	Sid         string // 50
	ResultCode  string // 8
	ReqTime     string // 17
	RspTime     string // 17
	ClientIp    string // 40
	DevInfo     string // 5
	OsInfo      string // 50
	NwInfo      string // 5
	SvcName     string // 32
	DevModel    string // 50
	CarrierType string // 1
	HostName    string // 32
	ScnName     string // 32

	//not necessary
	CallId     string // 60
	TrId       string // 100
	ConcCall   string // 5
	SvcType    string // 20
	SvcReqTime string // 17
	SvcRspTime string // 17
	TransferNo string // 20
	CallTime   string // 5
	CallType   string // 10
	FunName    string // 30
	ResultMsg  string // 256
	SttText    string // 8192
	TtsText    string // 1024
}

const (
	//necessary value
	STAT_INFO    = 0
	SEQ_ID       = STAT_INFO + 25
	LOG_TIME     = SEQ_ID + 14
	LOG_TYPE     = LOG_TIME + 3
	SID          = LOG_TYPE + 50
	RESULT_CODE  = SID + 8
	REQ_TIME     = RESULT_CODE + 17
	RES_TIME     = REQ_TIME + 17
	CLIENT_IP    = RES_TIME + 40
	DEV_INFO     = CLIENT_IP + 5
	OS_INFO      = DEV_INFO + 50
	NW_INFO      = OS_INFO + 5
	SVC_NAME     = NW_INFO + 32
	DEV_MODEL    = SVC_NAME + 50
	CARRIER_TYPE = DEV_MODEL + 1
	HOST_NAME    = CARRIER_TYPE + 32
	SCN_NAME     = HOST_NAME + 32

	//not necessary
	CALL_ID      = SCN_NAME + 60
	TR_ID        = CALL_ID + 100
	CONC_CALL    = TR_ID + 5
	SVC_TYPE     = CONC_CALL + 20
	SVC_REQ_TIME = SVC_TYPE + 17
	SVC_RSP_TIME = SVC_REQ_TIME + 17
	TRANSFER_NO  = SVC_RSP_TIME + 20
	CALL_TIME    = TRANSFER_NO + 5
	CALL_TYPE    = CALL_TIME + 10
	FUN_NAME     = CALL_TYPE + 30
	RESULT_MSG   = FUN_NAME + 255
	STT_TEXT     = RESULT_MSG + 8192
	TTS_TEXT     = STT_TEXT + 1024
)

func ListenStatMNG() (icserr *icserror.IcsError) {
	l := icslog.GetIcsLog()
	conf := icsconf.GetIcsConfig()

	//start bot-command listen
	statPort := conf.Target.TargetPort
	statTransport := conf.Target.Transport
	statLocalAddrStr := fmt.Sprintf("0.0.0.0:%d", statPort)
	statLocalAddr := icsnet.NewNetAddrWithIPAddr(statLocalAddrStr)

	var cmdErr *icserror.IcsError
	statTCP, cmdErr := icsnet.ListenAndServeTCP(&statLocalAddr, nil, "\r\n\r\n", StatsCommand)
	if cmdErr != nil {
		l.Printf(icslog.LOG_LEVEL_FATAL, -1, "%s", cmdErr.GetError())
		return nil
	}
	l.Printf(icslog.LOG_LEVEL_INFO, -1, "Listening Stat TCP Command %s port[%d]", statTransport, statPort)
	fmt.Println(statTCP)

	return nil
}

func StatsCommand(t *icsnet.IcsTCPNet, bufend string) {
	l := icslog.GetIcsLog()
	statInfos := new(StatInfos)

	count := 0

	defer t.Close()
	l.Printf(icslog.LOG_LEVEL_INFO, -1, "Connected from - %s", t.RemoteAddr())

	for {
		statReads, rlen, rerr := t.ReadS(10137, bufend) // 여기서 전체 몇 byte씩 읽어서 로그를 찍을건지 알아야함
		if rerr != nil {
			if rerr.GetError() != io.EOF {
				l.Printf(icslog.LOG_LEVEL_ERROR, -1, "[Stat Command] ReadS Error! - %s[%d:%d]",
					rerr.GetError(), rlen, len(statReads))
				// t.Close()
			}
			continue
		} else {
			seqId := fmt.Sprintf("%05d", count)
			fmt.Printf("Recved Stat Command(%s) %d \n", statReads, rlen)
			statInfos.ChangeByteToString(statReads)

			insLog := ""
			// insLog += fmt.Sprintf("%s\n", statInfos.CallId)
			insLog += fmt.Sprintf("seqId:%s\n", seqId)
			// insLog += fmt.Sprintf("%s\n", statInfos.SeqId)
			insLog += fmt.Sprintf("LogTime:%s, ", statInfos.LogTime)
			insLog += fmt.Sprintf("LogType:%s, ", statInfos.LogType)
			insLog += fmt.Sprintf("Sid:%s, ", statInfos.Sid)
			insLog += fmt.Sprintf("ResultCode:%s, ", statInfos.ResultCode)
			insLog += fmt.Sprintf("ReqTime:%s, ", statInfos.ReqTime)
			insLog += fmt.Sprintf("RspTime:%s, ", statInfos.RspTime)
			insLog += fmt.Sprintf("ClientIp:%s, ", statInfos.ClientIp)
			insLog += fmt.Sprintf("DevInfo:%s, ", statInfos.DevInfo)
			insLog += fmt.Sprintf("OsInfo:%s, ", statInfos.OsInfo)
			insLog += fmt.Sprintf("NwInfo:%s, ", statInfos.NwInfo)
			insLog += fmt.Sprintf("SvcName:%s, ", statInfos.SvcName)
			insLog += fmt.Sprintf("DevModel:%s, ", statInfos.DevModel)
			insLog += fmt.Sprintf("CarrierType:%s, ", statInfos.CarrierType)
			insLog += fmt.Sprintf("HostName:%s, ", statInfos.HostName)
			insLog += fmt.Sprintf("ScnName:%s, ", statInfos.ScnName)
			insLog += fmt.Sprintf("CallId:%s, ", statInfos.CallId)
			insLog += fmt.Sprintf("TrId:%s, ", statInfos.TrId)
			insLog += fmt.Sprintf("ConcCall:%s, ", statInfos.ConcCall)
			insLog += fmt.Sprintf("SvcType:%s, ", statInfos.SvcType)
			insLog += fmt.Sprintf("SvcReqTime:%s, ", statInfos.SvcReqTime)
			insLog += fmt.Sprintf("SvcRspTime:%s, ", statInfos.SvcRspTime)
			insLog += fmt.Sprintf("TransferNo:%s, ", statInfos.TransferNo)
			insLog += fmt.Sprintf("CallTime:%s, ", statInfos.CallTime)
			insLog += fmt.Sprintf("CallType:%s, ", statInfos.CallType)
			insLog += fmt.Sprintf("FunName:%s, ", statInfos.FunName)
			insLog += fmt.Sprintf("ResultMsg:%s, ", statInfos.ResultMsg)
			insLog += fmt.Sprintf("SttText:%s, ", statInfos.SttText)
			insLog += fmt.Sprintf("TtsText:%s", statInfos.TtsText)

			l.Printf(icslog.LOG_LEVEL_INFO, -1, "%s", insLog)
			fmt.Printf("stats- %s \n", statInfos.SeqId)
			fmt.Printf("stats- %s \n", statInfos.LogTime)
			fmt.Printf("stats- %s \n", statInfos.LogType)
			fmt.Printf("stats- %s \n", statInfos.Sid)
			fmt.Printf("stats- %s \n", statInfos.ResultCode)
			fmt.Printf("stats- %s \n", statInfos.ReqTime)
			fmt.Printf("stats- %s \n", statInfos.RspTime)
			fmt.Printf("stats- %s \n", statInfos.ClientIp)
			fmt.Printf("stats- %s \n", statInfos.DevInfo)
			fmt.Printf("stats- %s \n", statInfos.OsInfo)
			fmt.Printf("stats- %s \n", statInfos.NwInfo)
			fmt.Printf("stats- %s \n", statInfos.SvcName)
			fmt.Printf("stats- %s \n", statInfos.DevModel)
			fmt.Printf("stats- %s \n", statInfos.CarrierType)
			fmt.Printf("stats- %s \n", statInfos.HostName)
			fmt.Printf("stats- %s \n", statInfos.ScnName)
			fmt.Printf("stats- %s \n", statInfos.CallId)
			fmt.Printf("stats- %s \n", statInfos.TrId)
			fmt.Printf("stats- %s \n", statInfos.ConcCall)
			fmt.Printf("stats- %s \n", statInfos.SvcType)
			fmt.Printf("stats- %s \n", statInfos.SvcReqTime)
			fmt.Printf("stats- %s \n", statInfos.SvcRspTime)
			fmt.Printf("stats- %s \n", statInfos.TransferNo)
			fmt.Printf("stats- %s \n", statInfos.CallTime)
			fmt.Printf("stats- %s \n", statInfos.CallType)
			fmt.Printf("stats- %s \n", statInfos.FunName)
			fmt.Printf("stats- %s \n", statInfos.ResultMsg)
			fmt.Printf("stats- %s \n", statInfos.SttText)
			fmt.Printf("stats- %s \n", statInfos.TtsText)
			// l.Printf(icslog.LOG_LEVEL_INFO, -1, "Recved Stat Command(%s) %d", ttsHeader, rlen)
			count++
			// t.Close()
		}
	}
}

func (statInfos *StatInfos) ChangeByteToString(statInfo []byte) *icserror.IcsError {
	// l := icslog.GetIcsLog()

	// defer func() {
	// 	l.Printf(icslog.LOG_LEVEL_WARN, -1, "%s \n%s",
	// 		icserror.ICSERRNETNotConnectError.GetMessage(), debug.Stack())
	// 	return
	// }()

	// n := bytes.Index(statInfo[STAT_INFO:SEQ_ID], []byte{0})
	statInfos.SeqId = string(statInfo[STAT_INFO:SEQ_ID])
	// fmt.Println("seqid ", statInfo[STAT_INFO : SEQ_ID])

	// n := bytes.Index(statInfo[SEQ_ID:LOG_TIME], []byte{0})
	statInfos.LogTime = string(statInfo[SEQ_ID:LOG_TIME])
	// fmt.Println("seqid ", statInfo[SEQ_ID : SEQ_ID+n])

	// n = bytes.Index(statInfo[LOG_TIME:LOG_TYPE], []byte{0})
	statInfos.LogType = string(statInfo[LOG_TIME:LOG_TYPE])
	// fmt.Println("seqid ", statInfo[SEQ_ID : SEQ_ID+n])

	// n = bytes.Index(statInfo[LOG_TYPE:SID], []byte{0})
	statInfos.Sid = string(statInfo[LOG_TYPE:SID])

	// n = bytes.Index(statInfo[SID:RESULT_CODE], []byte{0})
	statInfos.ResultCode = string(statInfo[SID:RESULT_CODE])

	// n = bytes.Index(statInfo[RESULT_CODE:REQ_TIME], []byte{0})
	statInfos.ReqTime = string(statInfo[RESULT_CODE:REQ_TIME])

	// n = bytes.Index(statInfo[REQ_TIME:RES_TIME], []byte{0})
	statInfos.RspTime = string(statInfo[REQ_TIME:RES_TIME])

	// n = bytes.Index(statInfo[RES_TIME:CLIENT_IP], []byte{0})
	statInfos.ClientIp = string(statInfo[RES_TIME:CLIENT_IP])

	// n = bytes.Index(statInfo[CLIENT_IP:DEV_INFO], []byte{0})
	statInfos.DevInfo = string(statInfo[CLIENT_IP:DEV_INFO])

	// n = bytes.Index(statInfo[DEV_INFO:OS_INFO], []byte{0})
	statInfos.OsInfo = string(statInfo[DEV_INFO:OS_INFO])

	// n = bytes.Index(statInfo[OS_INFO:NW_INFO], []byte{0})
	statInfos.NwInfo = string(statInfo[OS_INFO:NW_INFO])

	// n = bytes.Index(statInfo[NW_INFO:SVC_NAME], []byte{0})
	statInfos.SvcName = string(statInfo[NW_INFO:SVC_NAME])

	// n = bytes.Index(statInfo[SVC_NAME:DEV_MODEL], []byte{0})
	statInfos.DevModel = string(statInfo[SVC_NAME:DEV_MODEL])

	// n = bytes.Index(statInfo[DEV_MODEL:CARRIER_TYPE], []byte{0})
	statInfos.CarrierType = string(statInfo[DEV_MODEL:CARRIER_TYPE])

	// n = bytes.Index(statInfo[CARRIER_TYPE:HOST_NAME], []byte{0})
	statInfos.HostName = string(statInfo[CARRIER_TYPE:HOST_NAME])

	// n = bytes.Index(statInfo[HOST_NAME:SCN_NAME], []byte{0})
	statInfos.ScnName = string(statInfo[HOST_NAME:SCN_NAME])

	// n = bytes.Index(statInfo[SCN_NAME:CALL_ID], []byte{0})
	statInfos.CallId = string(statInfo[SCN_NAME:CALL_ID])

	// n = bytes.Index(statInfo[CALL_ID:TR_ID], []byte{0})
	statInfos.TrId = string(statInfo[CALL_ID:TR_ID])

	// n = bytes.Index(statInfo[TR_ID:CONC_CALL], []byte{0})
	statInfos.ConcCall = string(statInfo[TR_ID:CONC_CALL])

	// n = bytes.Index(statInfo[CONC_CALL:SVC_TYPE], []byte{0})
	statInfos.SvcType = string(statInfo[CONC_CALL:SVC_TYPE])

	// n = bytes.Index(statInfo[SVC_TYPE:SVC_REQ_TIME], []byte{0})
	statInfos.SvcReqTime = string(statInfo[SVC_TYPE:SVC_REQ_TIME])

	// n = bytes.Index(statInfo[SVC_REQ_TIME:SVC_RSP_TIME], []byte{0})
	statInfos.SvcRspTime = string(statInfo[SVC_REQ_TIME:SVC_RSP_TIME])

	// n = bytes.Index(statInfo[SVC_REQ_TIME:SVC_RSP_TIME], []byte{0})
	statInfos.TransferNo = string(statInfo[SVC_RSP_TIME:TRANSFER_NO])

	// n = bytes.Index(statInfo[SVC_REQ_TIME:SVC_RSP_TIME], []byte{0})
	statInfos.CallTime = string(statInfo[TRANSFER_NO:CALL_TIME])

	// n = bytes.Index(statInfo[SVC_REQ_TIME:SVC_RSP_TIME], []byte{0})
	statInfos.CallType = string(statInfo[CALL_TIME:CALL_TYPE])

	// n = bytes.Index(statInfo[SVC_REQ_TIME:SVC_RSP_TIME], []byte{0})
	statInfos.FunName = string(statInfo[CALL_TYPE:FUN_NAME])

	// n = bytes.Index(statInfo[SVC_RSP_TIME:RESULT_MSG], []byte{0})
	statInfos.ResultMsg = string(statInfo[FUN_NAME:RESULT_MSG])

	// n = bytes.Index(statInfo[RESULT_MSG:STT_TEXT], []byte{0})
	statInfos.SttText = string(statInfo[RESULT_MSG:STT_TEXT])

	// n = bytes.Index(statInfo[STT_TEXT:TTS_TEXT], []byte{0})
	statInfos.TtsText = string(statInfo[STT_TEXT:])

	return nil
}
