// socket创建模块
// 秒寻科技
// zt 2024-08-30

package socketcreate

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"ipsomc/module/ps/psmodel"
	"ipsomc/module/ps/psul"
	"ipsomc/module/socket/socketsend"
	"ipsomc/util"
	"net"
	"os"
)

type SocketCreate struct {
	socketSendApi socketsend.SocketSend
	psUlApi       psul.PsUl
}

// 创建UDP Socket
func (obj *SocketCreate) CreateUdpSocket() {
	myViper := util.GetViper()
	hostaddress := myViper.GetString("socket.hostaddress")     //主机地址
	hostport := myViper.GetInt("socket.hostport")              //主机端口
	hostUrl := hostaddress + ":" + fmt.Sprintf("%d", hostport) //拼接url

	// 解析UPD地址和端口
	udpAddr, err := net.ResolveUDPAddr("udp", hostUrl)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	// 创建一个UDP连接并监听端口
	udpConn, err := net.ListenUDP("udp", udpAddr)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	defer udpConn.Close()
	obj.socketSendApi.SaveUdpConnHandle(udpConn)

	// 无限循环接收数据
	dataBuffer := make([]byte, 0, 2048) //接收缓存
	for {
		//将数据读到临时buffer中（ReadFromUDP方法会阻塞，直到有数据到达）
		tmpBuffer := make([]byte, 1024) //临时缓存
		n, clientAddr, err := udpConn.ReadFromUDP(tmpBuffer)
		if err != nil {
			fmt.Println(err.Error())
			return
		}
		dataBuffer = append(dataBuffer, tmpBuffer[:n]...) //把数据追加到数据缓存中

		//成帧处理，并且把数据发送给协议栈
		for len(dataBuffer) > psmodel.PS_FRAME_MIN_LEN { //数据长度大于最小帧长
			if dataBuffer[0] == psmodel.PS_AP_END_FLAG {
				// 查找数据包的结尾
				endIndex := bytes.IndexByte(dataBuffer[1:], psmodel.PS_AP_END_FLAG)
				if endIndex != -1 {
					// 找到了完整的数据包
					dataPacket := dataBuffer[0 : endIndex+2] // 包括结尾的0x7E
					dataBuffer = dataBuffer[endIndex+2:]     // 移除已处理的数据包，包括结尾的0x7E

					//开启goroutine，将数据报文发送给协议栈模块
					go obj.psUlApi.PsUl(clientAddr, dataPacket, len(dataPacket))

					fmt.Printf("Received %d bytes from %s\n", len(dataPacket), clientAddr)
				} else {
					// 没有找到结尾，等待更多数据
					break
				}
			} else {
				// 丢弃非法数据(数据以0x7E开头)，并等待更多数据
				dataBuffer = dataBuffer[1:]
			}
		}
	}
}

// 创建TCP Socket
func (obj *SocketCreate) CreateTcpSocket() {
	myViper := util.GetViper()
	hostaddress := myViper.GetString("socket.hostaddress")     //主机地址
	hostport := myViper.GetInt("socket.hostport")              //主机端口
	hostUrl := hostaddress + ":" + fmt.Sprintf("%d", hostport) //拼接url

	// 解析地址和端口
	tcpAddr, err := net.ResolveTCPAddr("tcp", hostUrl)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}

	// 监听TCP地址
	listener, err := net.ListenTCP("tcp", tcpAddr)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	defer listener.Close()

	// 监听客户端连接
	for {
		conn, err := listener.AcceptTCP() //接收客户端连接
		if err != nil {
			fmt.Println("Error accepting:", err.Error())
			continue
		}

		// 开启goroutine，处理该连接
		go obj.HandleTcpConnection(conn)
	}
}

// 处理每一个TCP连接
func (obj *SocketCreate) HandleTcpConnection(conn *net.TCPConn) {
	defer conn.Close()

	//保存tcp连接句柄
	address := conn.RemoteAddr().String()
	obj.socketSendApi.SaveTcpConnHandle(conn, address)

	//监听TCP连接上的数据
	reader := bufio.NewReader(conn)
	dataBuffer := make([]byte, 0, 2048) //接收缓存
	for {
		tmpBuffer := make([]byte, 1024)  //临时缓存
		n, err := reader.Read(tmpBuffer) //从客户端读取数据
		if err != nil && err != io.EOF {
			fmt.Println("Error reading:", err.Error())
			obj.socketSendApi.DeleteTcpConnHandle(address) //删除一个tcp连接
			break
		}
		dataBuffer = append(dataBuffer, tmpBuffer[:n]...) //把数据追加到数据缓存中

		//成帧处理，并且把数据发送给协议栈
		for len(dataBuffer) > psmodel.PS_FRAME_MIN_LEN { //数据长度大于最小帧长
			if dataBuffer[0] == psmodel.PS_AP_END_FLAG {
				// 查找数据包的结尾
				endIndex := bytes.IndexByte(dataBuffer[1:], psmodel.PS_AP_END_FLAG)
				if endIndex != -1 {
					// 找到了完整的数据包
					dataPacket := dataBuffer[0 : endIndex+2] // 包括结尾的0x7E
					dataBuffer = dataBuffer[endIndex+2:]     // 移除已处理的数据包，包括结尾的0x7E

					//开启goroutine，将数据报文发送给协议栈模块
					go obj.psUlApi.PsUlTcp(address, dataPacket, len(dataPacket))

					fmt.Printf("Received %d bytes from %s\n", len(dataPacket), address)
				} else {
					// 没有找到结尾，等待更多数据
					break
				}
			} else {
				// 丢弃非法数据(数据以0x7E开头)，并等待更多数据
				dataBuffer = dataBuffer[1:]
			}
		}

	}
}
