package main

import (
	"log"
	"net"
	//"os"
	// "strconv"
	// "log"
	//"strings"
	"time"
	// "go-study/socket/config"
	"bytes"
	"strconv"

)

func handleConn(conn net.Conn) {

	if connTest==nil{
		connTest = conn
	}

	log.Println("yunhorndeug.push.data.tcp.begin handleConn,cliendAddr:", conn.RemoteAddr())

	defer conn.Close()

	readChan := make(chan []byte)
	//writeChan := make(chan string)
	stopChan := make(chan bool)

	go readConn(conn, readChan, stopChan)
	// go writeConn(conn, writeChan, stopChan)

	var heartbeat []byte = []byte{0x01}

	for {
		select {
		case readStr := <-readChan:
			//log.Println("readStr:",readStr)
			//upper := strings.ToUpper(readStr)
			//writeChan <- upper

			// go yunhorn_ys_l_v1(readStr)
			go yunhorn_wireless(readStr)
		case stop := <-stopChan:
			if stop {
				log.Println("stop channel")
				break
			}
		case <-time.After(5000 * time.Millisecond):
			_, err := conn.Write(heartbeat)
			if err != nil {
				log.Println("write msg error!", err)
				stopChan <- true
			} else {
				//log.Println("write msg success!", conn.RemoteAddr())

				//暂时写死,演示用  lora心跳包给云端
				var device Device
				device.Lock()
				device.ID = "6F3A8B2D-B0DF-404A-AA7E-4A4086BD0B56"
				device.VERSION = "yunhorn_lora_l_v1"
				device.ONLINE = true
				device.DATA = make(map[string]interface{})
				device.DATA["data"] = 1
				//go send_data(1005, device)
			}
		}
	}
}

func readConn(conn net.Conn, readChan chan<- []byte, stopChan chan<- bool) {

	data := make([]byte, 256)
	Rdata2 := make([]byte, 0)

	for {
		reqLen, err := conn.Read(data)
		if err != nil {
			log.Println(err)
			break
		}

		buffer := new(bytes.Buffer)
		continueCount := 0
		// log.Println("yunhorndeug.push.data.tcp.reqLen|data",reqLen,data)
		log.Println("$$$$$$$$$$$$$$$$$$$$$$$$$",data[:reqLen])
    for i, b := range data[:reqLen] {

				if reqLen<7{
					break
				}

			  if continueCount>0{
					continueCount--
					continue;
				}

				if b!=254{
					s := strconv.FormatInt(int64(b&0xff), 16)
	        if len(s) == 1 {
	            buffer.WriteString("0")
	        }
	        buffer.WriteString(s)
				}

				// log.Println("========================",data[reqLen-2:reqLen])

				// log.Println(b)
				// log.Println("$$$$$$$$$$$$$$$$$$$$$$$$$",i,reqLen)
				// log.Println("$$$$$$$$$$$$$$$$$$$$$$$$$",data[reqLen])
				end :=0
				//254为分隔符
				if b==254 && i>3{
					addrs := data[i-4:i]

					//尿布台数据,地址1位 数据2位
					dataType := data[i+1]
					values := make([]byte,0)
					if data[i+1] == 1 {

						continueCount = 3
						end = 4

						if i+4>reqLen{
							log.Println("yunhorndeug.push.data.tcp.fq",buffer.String(),addrs,dataType)
							continue
						}

						//类型为1 数据量为2
						values = data[i+2:i+4]

					}else if dataType == 2{
						//类型为2 数据量位1

						continueCount = 2
						end = 3

						if i+3 >reqLen{
							log.Println("yunhorndeug.push.data.tcp.fq",buffer.String(),addrs,dataType)
							continue
						}
						values = data[i+2:i+3]
					}else if dataType ==4 {
						//空气质量
						continueCount = 18
						end = 19
						if i+end >reqLen{
							log.Println("yunhorndeug.push.data.tcp.fq",buffer.String(),addrs,dataType)
							continue
						}
						values = data[i+2:i+end]

						log.Println("pm25data1",data[i+15])
						log.Println("pm25data2",data[i+16])
						// nh3data := uint32(data[i+7])*256+uint32(data[i+8])
						pm25data := uint32(data[i+15])*256+uint32(data[i+16])
						log.Println("nh3data",data[i+7])
						log.Println("pm25data",pm25data)

						//8E 3C 00 00 47 46
						var close []byte = []byte{0x8E,0x3C,0x00,0x00,0x43,0x46}
						var open []byte = []byte{0x8E,0x3C,0x00,0x00,0x4F,0x46}
						var writedata []byte =[]byte{}
						//i+7  氨气
						//i+14 tvoc 甲醛
						if pm25data>100 || data[i+7]>=3 || data[i+14]>=2 {
							writedata = open
						}else{
							writedata = close
						}
						v, err := connTest.Write(writedata)
						log.Println("send.msg.conn.RemoteAddr:",connTest.RemoteAddr(),writedata)
						log.Println("send.msg.conn.v",v)
						if err != nil {
							log.Println("write msg error!", err)
						}
					}else if dataType ==3{
						continueCount = 2
						end = 3

						if i+3 >reqLen{
							log.Println("yunhorndeug.push.data.tcp.fq",buffer.String(),addrs,dataType)
							continue
						}

						// values = data[i+2:i+3]
						values := data[i+2]

						//28 3C 00 00 47 46
						var green []byte = []byte{0x28,0x3C,0x00,0x00,0x47,0x46}
						var red []byte = []byte{0x28,0x3C,0x00,0x00,0x52,0x46}

						var yellow []byte = []byte{0x28,0x3C,0x00,0x00,0x59,0x46}
						var writedata []byte =[]byte{}
						writedata = green
						if values == 2{
							writedata = red
						}else if values == 1{
							writedata = green
						}else if values == 4{
							writedata = yellow
						}
						log.Println("send.msg.conn.RemoteAddr|writedata",connTest.RemoteAddr(),writedata)
						v, err := connTest.Write(writedata)

						log.Println("send.msg.conn.v",v)
						if err != nil {
							log.Println("write msg error!", err)
						}

					}

					log.Println("yunhorndeug.push.data.tcp:",buffer.String(),addrs,dataType,values)
					// log.Println("yunhorndeug.push.data.tcp.addr",addrs)
					// log.Println("yunhorndeug.push.data.tcp.type",dataType)
					// log.Println("yunhorndeug.push.data.tcp.values",values)

					_,ok := loraNodeMap.Load(buffer.String())
					if !ok{
						log.Println("yunhorndeug.push.data.tcp.dev not exist:",buffer.String())
							buffer = new(bytes.Buffer)
						continue
					}

						buffer = new(bytes.Buffer)


					// if(dataType ==1 || dataType ==2 || dataType == 4 ){
					 	go dealDatav3(data[i-4:i+end])
					// }

				}
    }


    // 转化为字符串
    // log.Println("yunhorndeug.push.data.tcp.16data:",buffer.String())

		Rdata2 = make([]byte, reqLen)
		for i,v := range  data[:reqLen]{
			Rdata2[i]=v
		}

		// log.Println("===========================yunhorndeug.push.data.tcp.origin.Rdata:",Rdata2)

		// Rdata2 = make([]byte, count)

		// log.Println("read.data:%d,%s", Bytes2Bits(data[3:4])[0],conn.RemoteAddr())

		// data_buf <- data

		data = make([]byte, 256)
	}

	stopChan <- true
}

func writeConn(conn net.Conn, writeChan <-chan string, stopChan chan<- bool) {
	for {
		strData := <-writeChan
		_, err := conn.Write([]byte(strData))
		if err != nil {
			log.Println(err)
			break
		}

		log.Println("Send:", strData)
	}

	stopChan <- true
}