package main

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

/**
* 从loragw的组中获取到范围内的所有node,给符合addr的node发送command
**/

func sendCommand(addr string, command int) {
	log.Println("begin sendCommand")
	log.Println("yunhorn.loragw.sendCommand|", addr, command)
	commands := []byte{0x01}
	byteAddr, ok := sensorMap.Load(addr)
	if !ok {
		log.Println("send command fail,invalid addr|", addr)
		return
	}

	loraNode, ok := loraNodeMap.Load(addr)
	if !ok {
		log.Println("send command fail,invalid addr|", addr)
		return
	}
	if command == 1 {
		commands = []byte{0x01}
	} else if command == 2 {
		commands = []byte{0x02}
	} else {
		log.Println("send command fail,invalid command|", command)
		return
	}

	// strconv.Itoa
	var buffer bytes.Buffer
	buffer.Write(byteAddr.([]byte))
	buffer.Write(commands)

	// log.Println("loragws ",loraNode.(LoraNode).LORA_GWS)

	for _, loragwip := range loraNode.(LoraNode).LORA_GWS {
		loraconn, ok := loragwMap.Load(loragwip)
		if ok {
			log.Println("yunhorn.loragw.begin push tcp command ", buffer.Bytes())
			_, err := loraconn.(net.Conn).Write(buffer.Bytes())
			if err != nil {
				log.Println("yunhorn.loragw.write msg error!", err)
				return
			}
		}
	}
}

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])
		now := time.Now()
		// log.Println("yunhorndeug.push.data.tcp.begin handleConn,cliendAddr:", conn.RemoteAddr())

		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)
			}

			end := 0
			//254为分隔符
			if b == 254 && i > 3 {
				addrs := data[i-4 : i]

				//尿布台数据,地址1位 数据2位
				dataType := data[i+1]

				//0是通用类型 命令交互
				if dataType != 0 && dataType != 1 && dataType != 2 && dataType != 3 && dataType != 4 {
					continue
				}

				values := make([]byte, 0)

				if dataType == 0 {
					continueCount = 2
					end = 3
					values = data[i+2 : i+3]
				} else if dataType == 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 = 19
					end = 20
					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+end]
					// 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)

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

				if !loraNode.(LoraNode).UPDATE_TIME.IsZero() {
					var duration = now.Sub(loraNode.(LoraNode).UPDATE_TIME).Seconds()
					var durationAsInt64 = int(duration)
					if durationAsInt64 <= 1 {
						log.Println("repeat.sensor.data:", addrs)
						continue
					}
				}

				sensorMap.Store(buffer.String(), addrs)

				buffer = new(bytes.Buffer)

				if conf.RECORD_LOG_PATH != "" {
					go write_log_channel(data[i-4 : i+end])
				}

				go dealDatav3(data[i-4:i+end], conn.RemoteAddr().String())

			}
		}

		// 转化为字符串
		// 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
}