package main

import (
	"database/sql"
	// "encoding/json"

	"os"

	// _ "github.com/mattn/go-sqlite3"

	// "strconv"
	"math/rand"
	"sync"
	"time"

	"k8s.io/apimachinery/pkg/util/yaml"

	"bytes"
	"io/ioutil"
)

type Traffic struct {
	TRAFFIC uint16 `json:"traffic"`
}

type Satisfaction struct {
	SATISFACTION float64 `json:"satisfaction"`
}

type Conf struct {
	GATEWAY_INFO     Gateway_info            `json:"gateway_info"`
	DEVICES_LIST     [][]string              `json:"devices_list`
	SERIALPORTS_LIST map[string]Serialconf   `json:"serialports_list"`
	RS485DEVICES     map[string]Rs485devices `json:"rs485devices"`
	ICONURL          string                  `json:"iconurl`
	WEBSOCKETURL     []string                `json:"websocketurl"`
	POST_TO_SERVER   string                  `json:"post_to_server"`
	DEBUG            bool                    `json:"debug"`
	//是否初始化时打开串口
	OPENSERIAL bool `json:"openserial"`
	//无线 设备
	WIRELESSSLAVEDEVICES []WirelessSlaveDevice `json:"wireless_slave_devices"`
	//是否启动tcpserver
	OPENTCPSETVER             bool       `json:"open_tcp_server"`
	CHECKSERIAL               bool       `json:"check_serial"`
	LORANODES                 []LoraNode `json:"lora_nodes"`
	DPARKLOCATION             string     `json:"dpark_location"`
	TCPPORT                   int        `json:"tcp_port"`
	APIPORT                   int        `json:"api_port"`
	PROCATEGORY               int        `json:"pro_category"`
	SYNDATA                   bool       `json:"syn_data"`
	SYNEXTENSIONTIME          bool       `json:"syn_extension_Time"`
	RECORD_LOG_PATH           string     `json:"record_log_path"`
	RECORD_LOG_RETENTION_TIME int        `json:"record_log_retention_time"`
	MQTT_OPEN                 bool       `json:"mqtt_open"`
	MQTT_BROKER               string     `json:"mqtt_broker"`
	MQTT_USERNAME             string     `json:"mqtt_username"`
	MQTT_PASSWORD             string     `json:"mqtt_password"`
	MQTT_KEEPALIVE            int        `json:"mqtt_keepAlive"`
	MQTT_TOPIC                string     `json:"mqtt_topic"`
	MQTT_TIMEOUT              int        `json:"mqtt_timeout"`
}

//无线 下位机
type WirelessSlaveDevice struct {
	ADRH    int    `json:"adrh"`
	ADRL    int    `json:"adrl"`
	TYPE    int    `json:"type"`
	VERSION string `json:"version"`
	FLIP    bool   `json:"flip"`
	ID      string `json:"id"`
}

type Gateway_info struct {
	ID       string    `json:"id"`
	VERSION  string    `json:"version"`
	LOCATION []float64 `json:"location"`
	UNITNAME string    `json:"单位"`
	CONFIG   []Config  `json:"config"`
}

type Config struct {
	ID      string          `json:"id"`
	VERAION string          `json:"version"`
	DATA    [][]interface{} `json:"data"`
}

type Rs485devices struct {
	VERSION string   `json:"version"`
	NUM     string   `json:"num"`
	COMMAND [][]byte `json:"command"`
}

type Serialconf struct {
	COM         string `json:"com"`
	BAUDS       int    `json:"bauds"`
	SIZE        uint16 `json:"size"`
	PARITY      string `json:"parity"`
	STOPBITS    int    `json:"stopbits"`
	READTIMEOUT int    `json:"readtimeout"`
	NOTE        string `json:"note"`
}

type LoraNode struct {
	ADR           string    `json:"adr"`
	LOCATION_TYPE string    `json:"location_type"`
	LOCATION_CODE string    `json:"location_code"`
	LOCATION_DATA string    `json:"location_data"`
	TIME          time.Time `json:"time"`
	CURRENT_DATA  int       `json:"current_data"`
	CHECK_TIME    bool      `json:"check_time"`
	DEVICE        string    `json:"device"`
	UPDATE_TIME   time.Time `json:"update_time"`
	LORA_GWS      []string  `json:"lora_gws"`
}

var conf Conf
var DEVICEDATAS Devicedatas
var demoDevice Device

var today string

var nodeUpdateMap sync.Map

//sensor data update map
var sensorUpdateMap sync.Map

//key:loragateway ip value:conn object
var loragwMap sync.Map

//key:字符串addr  value:byte[] addr
var sensorMap sync.Map

//log channel
var logch = make(chan []byte)

var loraNodeMap sync.Map

var db, _ = sql.Open("sqlite3", "./db/gateway.db")

type pluginConfig struct {
	PodNodeSelectorPluginConfig map[string]string
}

// 加载配置文件
func init() {

	//以时间配置随机数种子
	rand.Seed(time.Now().UnixNano())

	t := time.Now()
	today = t.Format("2006-01-02")

	// configfile, err := os.Open("conf/gateway.conf")
	// check(err)
	// defer configfile.Close()

	// err = json.NewDecoder(configfile).Decode(&conf)
	// check(err)

	configfile, err := os.Open("conf/gateway.yaml")
	check(err)
	defer configfile.Close()
	configData, err := ioutil.ReadAll(configfile)
	check(err)

	reader := bytes.NewReader(configData)
	// ext := runtime.RawExtension{}
	d := yaml.NewYAMLOrJSONDecoder(reader, 4096)

	// defaultConfig := &pluginConfig{}

	// if err := d.Decode(&defaultConfig); err != nil {
	// check(err)
	// }

	// log.Println("======================yaml.data:",defaultConfig)
	// return;

	if err = d.Decode(&conf); err != nil {
		// log.Println("conf parse error")
		check(err)
	}

	//post_to_server smartoilets.host
	// conf
	var SMARTOILETS_HOST string
	SMARTOILETS_HOST = os.Getenv("SMARTOILETS_HOST")
	if SMARTOILETS_HOST != "" {
		conf.POST_TO_SERVER = SMARTOILETS_HOST
	}

	// log.Println("conf:{}", conf.POST_TO_SERVER)

	var device Device

	// log.Println("slaveDevices:", conf.WIRELESSSLAVEDEVICES)

	for _, v := range conf.LORANODES {
		v.CURRENT_DATA = -1
		v.TIME = time.Now()
		loraNodeMap.Store(v.ADR, v)
	}

	DEVICEDATAS.Lock()
	DEVICEDATAS.DATA = make(map[string]Device)

	//初始化设备,目前conf.DEVICES_LIST
	for _, i := range conf.DEVICES_LIST {

		device.DATA = make(map[string]interface{})
		device.ID = i[0]
		device.VERSION = i[2]
		//版本号+编号
		DEVICEDATAS.DATA[i[2]+"_"+i[3]] = device
	}

	DEVICEDATAS.Unlock()

	// go dbdata_init()

}

var good, bad float64
var traffic_data Traffic
var satisfaction_data Satisfaction

// 初始化评价数据和人流量数据
// func dbdata_init() {
// 	rows, err := db.Query("SELECT good, bad FROM satisfaction order by id DESC limit 1")
// 	if err != nil {
// 		good = 1
// 		bad = 0

// 	} else {
// 		rows.Next()
// 		rows.Scan(&good, &bad)
// 		rows.Close()
// 	}
// 	//在原本没有db文件的情况下调用 会报错
// 	// rows.Close()
// 	rows, err = db.Query("SELECT traffic FROM traffic t where datetime(t.create_time) > datetime('now','start of day','-1 day') order by id DESC limit 1 ")
// 	if err != nil {
// 		traffic_data.TRAFFIC = 0
// 	} else {
// 		rows.Next()
// 		rows.Scan(&traffic_data.TRAFFIC)
// 		rows.Close()
// 	}
// }

// 定时更新评价数据和人流数据
// func savedata_cron() {
// 	T := time.Now().Format("2006-01-02")
// 	stmt, err := db.Prepare("UPDATE satisfaction set  good=?, bad=? ,create_time=? where id=(SELECT max(id) FROM satisfaction)")
// 	check(err)
// 	stmt.Exec(&good, &bad, &T)
// 	stmt, err = db.Prepare("UPDATE traffic set traffic=?, create_time=? where id=(SELECT max(id) FROM traffic)")
// 	check(err)
// 	stmt.Exec(&traffic_data.TRAFFIC, &T)
// }

// 每天0点插入一条数据
//TODO 刚好有人流量数据
// func insertdata() {
// 	T := time.Now().Format("2006-01-02")
// 	stmt, _ := db.Prepare(`INSERT INTO traffic (traffic, create_time) values (?, ?)`)
// 	stmt.Exec(&traffic_data.TRAFFIC, &T)
// 	traffic_data.TRAFFIC = 0
// }