// socket发送模块
// 秒寻科技
// zt 2024-09-30

package socketsend

import (
	"errors"
	"fmt"
	"ipsomc/core/dao/redis/redisapi"
	"ipsomc/module/socket/socketmodel"
	"ipsomc/public"
	"net"
)

// 定义全局变量
var gSocket_UdpConn *net.UDPConn = nil                 // UDP句柄
var GSocket_mapTcpConn = make(map[string]*net.TCPConn) //TCP连接map

type SocketSend struct {
}

// udp连接句柄
func (obj *SocketSend) SaveUdpConnHandle(udpConn *net.UDPConn) {
	gSocket_UdpConn = udpConn
}

// 保存TCP连接句柄
func (obj *SocketSend) SaveTcpConnHandle(tcpConn *net.TCPConn, address string) {
	GSocket_mapTcpConn[address] = tcpConn
}

// 删除TCP连接句柄
func (obj *SocketSend) DeleteTcpConnHandle(address string) {
	delete(GSocket_mapTcpConn, address)
}

// 发送数据到基站
func (obj *SocketSend) SendDataToBts(projectId int, btsId int, apDataFrame []byte, wLen uint16) error {
	var redisObj redisapi.RedisApi
	udpClientAddr := &net.UDPAddr{}
	var udpClientAddrModel socketmodel.ClientAddr //客户端地址

	//组织redis建值，并查询客户端IP与端口
	redisKey := fmt.Sprintf("%08X", int(projectId)) + "-" + fmt.Sprintf("%08X", int(btsId)) //KEY
	if err := redisObj.GetModelData(redisKey, &udpClientAddrModel); err != nil {
		//删除map中的一个元素
		public.PublicDeleteOneItem(redisKey)
		return errors.New("该链接已过期")
	}

	//组织客户端地址
	ip := make(net.IP, net.IPv4len)    // 创建一个长度为4的切片，对应于 IPv4 地址
	copy(ip, udpClientAddrModel.IP[:]) // 复制字节到切片
	udpClientAddr.IP = ip
	udpClientAddr.Port = udpClientAddrModel.Port
	udpClientAddr.Zone = udpClientAddrModel.Zone

	//把数据发送至基站
	_, err := gSocket_UdpConn.WriteToUDP(apDataFrame, udpClientAddr)
	if err != nil {
		return err
	}

	println("send data to bts", apDataFrame[0], apDataFrame[len(apDataFrame)-1], len(apDataFrame))

	return nil
}

// 发送数据到基站
func (obj *SocketSend) SendDataToBtsTcp(projectId int, btsId int, apDataFrame []byte, wLen uint16) error {
	var redisObj redisapi.RedisApi
	var clientAddrModel socketmodel.ClientAddr //客户端地址

	//组织redis建值，并查询客户端IP与端口
	redisKey := fmt.Sprintf("%08X", int(projectId)) + "-" + fmt.Sprintf("%08X", int(btsId)) //KEY
	if err := redisObj.GetModelData(redisKey, &clientAddrModel); err != nil {
		//删除map中的一个元素
		public.PublicDeleteOneItem(redisKey)
		return errors.New("该链接已过期")
	}

	//获得tcp的连接
	conn, exist := GSocket_mapTcpConn[clientAddrModel.Address]
	if exist {
		//把数据发送至基站
		_, err := conn.Write(apDataFrame)
		if err != nil {
			return err
		}

		println("send data to bts", apDataFrame[0], apDataFrame[len(apDataFrame)-1], len(apDataFrame))
	}

	return nil
}
