package main

import (
	"io/ioutil"
	"log"
	"net"
	"os"
	"strconv"
	"time"

	"github.com/robfig/cron"
)

var err error

var bs = []byte(`
kind: Namespace
metadata:  #这是注释
   name: test
   list:
    - {id: 1,name: 张三,age: 12}
    - {id: 2,name: 李四,age: 13}
   data:
    - ["男厕位", 1]
    - ["男厕位", 2]
---

kind: bbb
name: aaa`)

/* Out put
{"kind":"Namespace","metadata":{"name":"test"}}
{"kind":"bbb","name":"aaa"}
*/
// func example() {
// 	reader := bytes.NewReader(bs)
// 	ext := runtime.RawExtension{}
// 	d := yaml.NewYAMLOrJSONDecoder(reader, 4096)
// 	//循环解析  yaml中---是分隔的意思,既一个yaml文件包含多个不同发json对象
// 	// for {
// 		if err := d.Decode(&ext); err != nil {
// 			if err == io.EOF {
// 				return
// 			}
// 			log.Println("parse err:",err)
// 			return
// 		}
// 		log.Println(string(ext.Raw))
// 	// }
// }

func main() {

	// example()

	// configfile, err := os.Open("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)
	// if err := d.Decode(&conf); err != nil {
	// 	if err == io.EOF {
	// 		return
	// 	}
	// 	log.Println("parse err:",err)
	// 	return
	// }
	// log.Println(string(ext.Raw))
	// err = json.NewDecoder(string(ext.Raw)).Decode(&conf)
	// check(err)
	// log.Println(conf.OPENTCPSETVER)

	go gw_router()
	go serial_run()
	c := cron.New()

	//获取数据防抖处理时间配置
	if conf.SYNEXTENSIONTIME {
		go getConf()
	}
	//有线方案,发送全部数据,包括gateway配置
	if conf.PROCATEGORY == PRO_CATEGORY_WIRED {
		go send_data(CODE1001)
	}

	//一分钟一次 同步数据
	c.AddFunc("0, *, *, *, *, *", func() {
		if conf.SYNDATA {
			if conf.PROCATEGORY == PRO_CATEGORY_WIRED {
				send_data(CODE1001)
			} else if conf.PROCATEGORY == PRO_CATEGORY_WIRELESS {
				yunhorn_hb_dpark_v1()
			}
		}
	})

	go ClearLog()

	c.AddFunc("0, *, *, *, *, *", func() {
		ClearLog()
	})

	// c.AddFunc("*/10, *, *, *, *, *", func() {
	// devices := []Device{}
	// log.Println(string(build_data(1001,devices)))
	// })

	c.AddFunc("*/30, *, *, *, *, *", func() {
		//dpark客户需要拉取api获取数据防抖时间配置
		if conf.SYNEXTENSIONTIME {
			getConf()
		}
	})

	// c.AddFunc("0, */10, *, *, *, *", savedata_cron)
	// c.AddFunc("0, 0, 0, *, *, *", insertdata)
	c.AddFunc("0, 0, *, *, *, *", get_weather)
	//定时更新today字段,当前日期
	c.AddFunc("0, *, *, *, *, *", func() {
		t := time.Now()
		today = t.Format("2006-01-02")
	})
	c.Start()

	if conf.OPENTCPSETVER {

		go record_log_channel()

		tcp_port := strconv.Itoa(conf.TCPPORT)

		listener, err := net.Listen("tcp", "0.0.0.0:"+tcp_port)
		if err != nil {
			log.Printf("listen fail, err: %v\n", err)
			return
		}

		for {
			conn, err := listener.Accept()
			loragwMap.Store(conn.RemoteAddr().String(), conn)
			if err != nil {
				log.Printf("accept fail, err: %v\n", err)
				continue
			}
			//       go process(conn)
			go handleConn(conn)
		}
	} else {
		//如果不启动tcpserver,则需要执行这里 让程序不退出
		select {}
	}

}

func check(err error) {
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
}

func checkErr(err error, exit bool) {
	if err != nil {
		log.Println(err)
		if exit {
			os.Exit(1)
		}
	}
}

func GetAllFile(pathname string) error {
	log.Println("begin for folder ", pathname)
	rd, err := ioutil.ReadDir(pathname)

	sep := string(os.PathSeparator)

	nowtime := time.Now()

	for _, fi := range rd {
		//",update time:" + fi.ModTime()
		// log.Printf("file is dir %b name : %s ", fi.IsDir(), fi.Name())

		var duration = nowtime.Sub(fi.ModTime()).Hours()
		var durationAsInt64 = int(duration) / 24

		if fi.IsDir() {
			// log.Println("begin in folder", pathname+sep+fi.Name(), fi.ModTime(), durationAsInt64)

			if durationAsInt64 > conf.RECORD_LOG_RETENTION_TIME {
				log.Println("begin read folder ", pathname+sep+fi.Name())
				rd2, err2 := ioutil.ReadDir(pathname + sep + fi.Name())
				if err2 != nil {
					log.Println("readir fail:", err2)
				}
				if len(rd2) == 0 {
					err3 := os.Remove(pathname + sep + fi.Name())
					if err3 != nil {
						log.Println("remove folder fail", pathname+sep+fi.Name(), err3)
					}
					// log.Println("delete folder name : %s %d", fi.Name(), len(rd2))
				}
			}

			GetAllFile(pathname + sep + fi.Name() + sep)
		} else {
			//RECORD_LOG_RETENTION_TIME conf
			// var duration = nowtime.Sub(loraNode.(LoraNode).TIME).Seconds()
			// var durationAsInt64 = int(duration)

			log.Println("file name:", fi.Name(), fi.ModTime(), durationAsInt64)

			if durationAsInt64 > conf.RECORD_LOG_RETENTION_TIME {
				log.Println("delete file name :", fi.Name())
				err3 := os.Remove(pathname + sep + fi.Name())
				if err3 != nil {
					log.Println("remove file fail", pathname+sep+fi.Name(), err3)
				}
			}

		}
	}
	return err
}

func ClearLog() {

	folder := conf.RECORD_LOG_PATH
	log.Println("logfile task begin ", folder)
	if folder != "" && conf.RECORD_LOG_RETENTION_TIME > 0 {
		err2 := os.MkdirAll(folder, os.ModePerm)
		if err2 != nil {
			log.Println(err2)
		}
		GetAllFile(folder)
	}
}