package FLXCheckInController
import (
	"fmt"
	"io"
	"reflect"
	"time"
	log "github.com/sirupsen/logrus"
)
type FlxCheckInCmdReader struct {
	BufferMaxLength  int
	SerialPort       *io.ReadWriteCloser
	tmpRecDataBuffer []byte
	IsRunning        bool
	//记录最后一次接收数据时间
	dtLastRecivedDateTime          time.Time
	InvokeOnBusinessDataReviceData func([]byte)
	OnConnectStatusHandler func(time.Time)
}
func (para *FlxCheckInCmdReader) InitPara(serialPortt *io.ReadWriteCloser) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("InitPara:", r)
		}
	}()
	fmt.Println("初始化串口驱动参数 ")
	para.SerialPort = serialPortt
	// Make sure to close it later.
	// defer port.Close()
	// // Write 4 bytes to the port.
	// b := []byte{0x00, 0x01, 0x02, 0x03}
	// n, err := port.Write(b)
	// port.Read()
	// if err != nil {
	// 	fmt.Println("port.Write: %v", err)
	// }
	// fmt.Println("Wrote", n, "bytes.")
}
// /// 接收到业务数据后触发事件
// public event BusinessDataReciveEventHandler OnBusinessDataReciveEventHandler;
// /// 读串口数据时发生的日志信息
// public event DataReciveLogHandler OnDataReciveLogHandler;
// /// 
// /// 判断串口设备的连接状态事件
// /// 
// public event DataReciveHandler OnConnectStatusHandler;
func (para *FlxCheckInCmdReader) InvokeOnDataReciveLogHandler(logMessage string) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("InvokeOnDataReciveLogHandler:", r)
		}
	}()
	// if OnDataReciveLogHandler != nil {
	// 	OnDataReciveLogHandler(logMessage)
	// }
	fmt.Println("串口消息:" + logMessage)
}
func (para *FlxCheckInCmdReader) InvokeOnConnectStatusHandler(dtLastRecived time.Time) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("InvokeOnConnectStatusHandler:", r)
		}
	}()
	para.OnConnectStatusHandler(dtLastRecived)
}
func (para *FlxCheckInCmdReader) ProcessRecvBuff(RecvBuffer []byte) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("ProcessRecvBuff:", r)
		}
	}()
	var PackLen int = 0
	var PackBuff []byte
	var startIndex int = 0
	var curIndex int = 0
	for curIndex < len(RecvBuffer) {
		//应该判断7E 06 或02
		if RecvBuffer[curIndex] == CMD_HEAD {
			if startIndex != curIndex && (curIndex-startIndex) >= 5 {
				PackLen = curIndex + 1 - startIndex
				PackBuff = make([]byte, PackLen)
				PackBuff = RecvBuffer[startIndex : startIndex+PackLen]
				para.InvokeOnBusinessDataReviceData(PackBuff) //外发事件。
				startIndex = curIndex + 1
			}
		}
		curIndex++
	}
	if startIndex != curIndex {
		para.tmpRecDataBuffer = append(para.tmpRecDataBuffer, RecvBuffer[curIndex:]...)
	}
}
func (para *FlxCheckInCmdReader) TimerCallbackHandler() {
	defer func() {
		if r := recover(); r != nil {
			log.Error("TimerCallbackHandler:", r)
		}
	}()
	var waitReadPackLen int = 0 //待读的字节长度
	// var length int = 0          //放入缓冲区的长度。
	for para.IsRunning {
		reciveData := make([]byte, 51200)
		clen, err := (*(para.SerialPort)).Read(reciveData)
		if err != nil {
			fmt.Println(err)
			if err == io.EOF {
				// time.Sleep(2000)
				// para.IsRunning = false
				// go	para.CloseDevice()
				// go para.TimerCallbackHandler()
				return
			}
			continue
		}
		if clen >= DataPacketMinLength {
			waitReadPackLen = clen
			if waitReadPackLen == 0 {
				fmt.Println(err)
			}
			data := make([]byte, waitReadPackLen)
			data = reciveData[:waitReadPackLen]
			//当前包接收长度 加上 上次接收半包的长度
			recvBuffer := make([]byte, len(para.tmpRecDataBuffer)+waitReadPackLen) //从端口读取数据的缓冲区
			//上次如果为半包
			if len(para.tmpRecDataBuffer) > 0 {
				recvBuffer = insertToSlice(0, para.tmpRecDataBuffer, recvBuffer)
				// id = PersonIDs[j]
			}
			recvBuffer = insertToSlice(len(para.tmpRecDataBuffer), data, recvBuffer)
			para.tmpRecDataBuffer = para.tmpRecDataBuffer[0:0]
			// recvBuffer = append(para.tmpRecDataBuffer, data...)
			//读取当前包的数据
			//Array.Copy(data, 0, recvBuffer, index, waitReadPackLen) //读来的数据先零时放入这个缓冲区
			para.ProcessRecvBuff(recvBuffer)
			para.dtLastRecivedDateTime = time.Now()
		} else {
			para.tmpRecDataBuffer = append(para.tmpRecDataBuffer, reciveData[:clen]...)
		}
	}
}
func (para *FlxCheckInCmdReader) Start() bool {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Start:", r)
		}
	}()
	// id = PersonIDs[j]
	//此处	para.IsRunning 如不设置,则程序无法接收签到门信息
	para.IsRunning = true
	fmt.Println("中控机接收开启")
	go para.TimerCallbackHandler()
	return true
}
func (para *FlxCheckInCmdReader) Stop() bool {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Stop:", r)
		}
	}()
	para.IsRunning = false
	return true
}
func (para *FlxCheckInCmdReader) ReadResponseData() []byte {
	defer func() {
		if r := recover(); r != nil {
			log.Error("ReadResponseData:", r)
		}
	}()
	if para.SerialPort == nil {
		return nil
	}
	reciveData := make([]byte, 51200)
	clen, err := (*(para.SerialPort)).Read(reciveData)
	if err != nil {
		fmt.Println("串口报错消息:" + err.Error())
		return nil
	}
	if clen <= 0 {
		return nil
	}
	// data := make([]byte, clen)
	data := reciveData[:clen]
	return data
}
// 截取字符串 start 起点下标 length 需要截取的长度
func Substr(str string, start int, length int) string {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Substr:", r)
		}
	}()
	rs := []rune(str)
	rl := len(rs)
	end := 0
	if start < 0 {
		start = rl - 1 + start
	}
	end = start + length
	if start > end {
		start, end = end, start
	}
	if start < 0 {
		start = 0
	}
	if start > rl {
		start = rl
	}
	if end < 0 {
		end = 0
	}
	if end > rl {
		end = rl
	}
	return string(rs[start:end])
}
// insertSlice 插入
func insertSlice(index int, newstr []byte, src []byte) (ns []byte) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("insertSlice:", r)
		}
	}()
	ns = append(ns, src[:index]...) // 切片后加..., 相当于拆包成单个元素
	ns = append(ns, newstr...)
	ns = append(ns, src[index+len(newstr):]...)
	return
}
func insertToSlice(index int, newstr []byte, src []byte) (ns []byte) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("insertToSlice:", r)
		}
	}()
	ns = append(ns, src[:index]...) // 切片后加..., 相当于拆包成单个元素
	ns = append(ns, newstr...)
	ns = append(ns, src[index:]...)
	return
}
func Contain(obj interface{}, target interface{}) bool {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Contain:", r)
		}
	}()
	targetValue := reflect.ValueOf(target)
	switch reflect.TypeOf(target).Kind() {
	case reflect.Slice, reflect.Array:
		for i := 0; i < targetValue.Len(); i++ {
			if targetValue.Index(i).Interface() == obj {
				return true
			}
		}
	case reflect.Map:
		if targetValue.MapIndex(reflect.ValueOf(obj)).IsValid() {
			return true
		}
	}
	return false
}
// RemoveElementToint32 移除数组内的指定元素
func RemoveElementStrings(list []string, value string) []string {
	defer func() {
		if r := recover(); r != nil {
			log.Error("RemoveElementStrings:", r)
		}
	}()
	var result = make([]string, 0)
	index := 0
	endIndex := len(list) - 1
	for i, s := range list {
		if s == value {
			result = append(result, list[index:i]...)
			index = i + 1
		} else if i == endIndex {
			result = append(result, list[index:endIndex+1]...)
		}
	}
	return result
}