package tcp

import (
	"fmt"
	"go.uber.org/zap"
	"net"
	"regexp"
	"server/dao"
	"server/global"
	"strconv"
	"strings"
	"time"
)

var (
	Devices = make(map[string]*Device) // 存储连接的全局 map
)

type Device struct {
	Info         dao.Screens
	Conn         net.Conn
	IsLogin      bool
	LastTime     time.Time
	SumHighSpeed int
	SumLowSpeed  int
}

// 实例所有设备
func InitDevices() {
	//// 将数据库中的设备全部离线
	//screens, _ := dao.QueryAllScreens()
	//for _, screen := range screens {
	//	Devices[screen.Sn] = &Device{Info: screen}
	//}
}

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

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 {
			// 从客户端读取数据的过程中发生错误 这里如果没读到可以视为设备离线了
			global.GVA_LOG.Error("read err,dev offLine")
			break
		}
		data := string(buf[:n])
		fmt.Println("读取", string(buf[:n]))
		if data[2:7] == "login" {
			s.Conn.Write([]byte("login:successful"))
		}

		if data[2:11] == "heartbeat" { //默认一分钟发一次心跳
			s.LastTime = time.Now()
			if !s.IsLogin {
				s.Conn.Write([]byte("{'trans':'on'}")) //开启上传状态
				screen, _ := dao.QueryScreensBySn(data[20:44])
				s.Info = screen
				s.IsLogin = true
				Devices[data[20:44]] = s
				_ = dao.UpdateScreensStatusBySn(s.Info.Sn, 1)
			} //更新上次发送心跳时间
			Devices[data[20:44]].Conn = s.Conn
			global.GVA_LOG.Info("设备心跳", zap.String("ScreensName", s.Info.ScreensName))
		}

		if strings.Contains(data, `"status":"highspeed"`) {
			s.SumLowSpeed = 0
			re := regexp.MustCompile(`"speed1":"(\d+)"`)
			match := re.FindStringSubmatch(data)
			if len(match) > 1 {
				speed1, _ := strconv.Atoi(match[1])
				if speed1 > 30 { //大于40认为超速
					s.SumHighSpeed++
					if s.SumHighSpeed >= 3 {
						fmt.Println("********************************************************************超速了")
					}
				} else {
					s.SumHighSpeed = 0
				}
			} else {
				fmt.Println("Speed1 not found")
				continue
			}
		}

		//判断低速
		if strings.Contains(data, `"status":"normalspeed"`) {
			s.SumHighSpeed = 0
			re := regexp.MustCompile(`"speed1":"(\d+)"`)
			match := re.FindStringSubmatch(data)
			if len(match) > 1 {
				speed1, _ := strconv.Atoi(match[1])
				if speed1 < 20 { //小于10认为低速
					s.SumLowSpeed++

					if s.SumLowSpeed >= 8 {
						fmt.Println("********************************************************************低低速了")
					}
				} else {
					s.SumLowSpeed = 0
				}
			} else {
				fmt.Println("Speed1 not found")
				continue
			}
		}

		//if strings.Contains(data, `"status":"none"`) {
		//	s.SumHighSpeed = 0
		//	s.SumLowSpeed = 0
		//}

	}
}

func IsOnline() {
	t := time.NewTicker(5 * time.Second) //每分钟
	for {
		select {
		case <-t.C:
			for _, device := range Devices {
				commond := `{
  "setdiscontent0": {
    "num": "5",
    "effect": "11",
    "speed": "3",
    "stay": "5",
    "total": "100",
    "color": "1",
    "content": "[24M]abc"
  }
}`
				n, err := Devices[device.Info.Sn].Conn.Write([]byte(commond))
				fmt.Println("我是n，", n)
				if err != nil {
					fmt.Println("err:", err)
				}
				fmt.Println("发送了。。。。。。。。。。。。。。。。。。。。。。")
				//符合条件
				if time.Now().Add(-2*time.Minute).After(device.LastTime) || device.LastTime.IsZero() {
					state := 0
					err := dao.UpdateScreensStatusBySn(device.Info.Sn, state)
					delete(Devices, device.Info.Sn)
					if err != nil {
						continue
					}
					device.Info.Status = 0
					global.GVA_LOG.Info("设备离线了", zap.String("ScreensName", device.Info.ScreensName))
				}
			}
		}
	}
}
