package tcp

import (
	"encoding/hex"
	"go.uber.org/zap"
	"net"
	"server/dao/devices"
	Dev "server/dao/devices"
	"server/model/common/request"
	"server/protocol"
	"server/utils/logger"
	"strings"
	"time"
)

var ScreenList []devices.Screens

type Device struct {
	info     devices.Screens
	conn     net.Conn
	lastTime time.Time
}

func (s *Device) Start(conn net.Conn) {
	s.conn = conn
	go s.Process()
	go s.Handle()
}

func (s *Device) Process() {
	// 函数执行完之后关闭连接
	defer s.conn.Close()
	for {
		buf := make([]byte, 256)
		// 将tcp连接读取到的数据读取到byte数组中, 返回读取到的byte的数目
		n, err := s.conn.Read(buf)
		if err != nil {
			// 从客户端读取数据的过程中发生错误
			logger.Logger.Errorf("read from client failed, err:%v", err)
			break
		}
		data := hex.EncodeToString(buf[:n])
		if !strings.Contains(strings.ToLower(data), "fe5c4b89") {
			continue
		}
		if len(data) > 51 {
			logger.Logger.Debugf("led sn = %v", data[34:50])
			ScreenList = devices.QueryAllScreens()
			for _, v := range ScreenList {
				if v.Sn == data[34:50] {
					s.info = v
					break
				}
			}
		}
		switch data[16:18] {
		case "61":
			logger.Logger.Debug("登录")
			// fe5c4b89 2a000000 62 00000000 17000000 31 23 32303233(年) 3035(月) 3135(日) 3031(星期) 3038(时) 3334(分) 3135(秒) 23 303630(心跳包时间) 23 ffff
			buffer := protocol.AuthDataPack{}.AuthLogin()
			s.conn.Write(buffer.Bytes())
		case "91":
			logger.Logger.Debug("心跳")
			if data[34:50] != s.info.Sn {
				continue
			}
			s.UpdateInfo(data[82:84], data[86:88], data[90:92])
		}
	}
}

func (s *Device) Handle() {
	t2 := time.NewTicker(3 * time.Minute) //在线监测
	for {
		select {
		case <-t2.C:
			state := request.DeviceStatus{
				Status:        1,
				PlayStatus:    s.info.PlayStatus,
				DisplayStatus: s.info.DisplayStatus,
				SourceStatus:  s.info.SourceStatus,
			}
			if time.Now().Add(-2 * time.Minute).After(s.lastTime) {
				//离线
				state.Status = 0
			} else {
				logger.Logger.Debugf("%s在线", s.info.ScreensCode)
			}
			//修改数据库状态
			err := Dev.UpdateScreensStatus(s.info.ScreensCode, state)
			if err != nil {
				logger.Logger.Error("UpdateScreensStatus err", zap.Error(err))
				continue
			}
			break
		default:
			continue
		}
	}
}

func (s *Device) UpdateInfo(playStatus, displayStatus, sourceStatus string) {
	play, display, source := 0, 0, 0
	if playStatus == "31" {
		play = 1
	}
	if displayStatus == "30" {
		display = 1
	}
	if sourceStatus == "30" {
		source = 1
	}
	s.info.Status = 1
	s.info.PlayStatus = play
	s.info.DisplayStatus = display
	s.info.SourceStatus = source
	s.lastTime = time.Now()
}
