// Package tcp -----------------------------
// @file      : tcpServer.go
// @author    : JJXu
// @contact   : wavingbear@163.com
// @time      : 2024/5/21 上午11:21
// -------------------------------------------
package tcp

import (
	"context"
	"esp8266Server/tcp/message"
	"fmt"
	"log"
	"net"
	"time"
)

var TcpServerIns *tcpServer

func InitTcpServer() {
	TcpServerIns = &tcpServer{
		clients: NewClientRoom(),
	}
	go TcpServerIns.Run()
	go TcpServerIns.runAutoPing()
}

type tcpServer struct {
	clients *ClientRoom
}

func (t *tcpServer) PingAllClient() {
	for _, mchId := range t.clients.GetMchIdList() {
		msg := fmt.Sprintf("002%s000ping", mchId)
		err := t.clients.SendMsg(mchId, msg)
		if err != nil {
			log.Printf("ping failed: mchid:[%s] err:[%s]\n", mchId, err.Error())
			continue
		}
		go t.clients.Reading(mchId)
	}
}

func (t *tcpServer) Run() {
	listener, err := net.Listen("tcp", ":8888")
	if err != nil {
		log.Fatal("TCP server failed to start: ", err)
	}
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println("TCP server failed to accept connection: ", err)
			return
		}
		//接收注册消息
		timeoutCtx, _ := context.WithTimeout(context.Background(), time.Second*30)
		go func() {
			for {
				select {
				case <-timeoutCtx.Done():
					conn.Close()
				default:
					var msg = make([]byte, 512)
					_, connErr := conn.Read(msg)
					if connErr != nil {
						break
					}
					registerMsg := message.CommonType(msg)
					if registerMsg.GetCmd() == "001" {
						log.Printf("TCP 注册设备[%s] 时间:[%s]\n", registerMsg.GetMchId(), time.Now().Format("2006-01-02 15:04:05"))
						t.clients.Save(registerMsg.GetMchId(), conn)
						//var mchId = registerMsg.GetMchId()
						//go t.clients.Reading(mchId)
						return
					} else {
						fmt.Println("注册失败,未知命令")
					}
				}

			}
		}()

	}
}
func (t *tcpServer) runAutoPing() {
	ticker := time.NewTicker(time.Second * 30)
	defer func() {
		ticker.Stop()
	}()
	for {
		select {
		case <-ticker.C:
			fmt.Println("auto ping. clients num:", len(t.clients.GetMchIdList()))
			t.PingAllClient()
		}
	}
}
func (t *tcpServer) SendMsg(mchId, msg string) error {
	return t.clients.SendMsg(mchId, msg)
}