package backend

import (
	"dhcp/global"
	"dhcp/internal/dao"
	"dhcp/model"
	"math/rand"
	"net"
	"strconv"
	"sync"
	"time"
)

type DHCPTemplate struct {
	DhcpInterface    string   //DHCP监听的端口
	IPAddressRanges  string   // ip范围
	DefaultGateway   string   // 默认网关
	NameServers      []string // DNS
	Hostname         string   // 主机名
	DomainName       string   // 域名
	BroadcastAddress string   // 广播地址
	NTPServers       []string // NTP服务器
	VLANID           string   // VLAN ID
	LeaseTime        int      // 租约
	Arch             string   // 架构
	DomainSearch     []string // 域名搜索
}

var record = make(map[string]struct{})  //记录分配的ip
var recordMac = make(map[string]string) //物理地址对应ip

func InitIPRecord() {
	all, err := dao.GetDHCP()
	if err != nil {
		global.Log.Info("初始化IP记录失败", err)
	}
	for _, v := range all {
		record[v.IPAddress] = struct{}{}
		recordMac[v.MACAddress] = v.IPAddress
	}
}

func UpdateRecord(mac string, ip string) {
	recordMac[mac] = ip
	delete(record, ip)
	record[ip] = struct{}{}
}

func DeleteRecord(mac string, ip string) {
	delete(record, ip)
	delete(recordMac, mac)
}

func CreateRecord(mac string, ip string) {
	record[ip] = struct{}{}
	recordMac[mac] = ip
}

func GenerateIP(mac string, ifName string) (model.DHCP, error) {
	var m sync.Mutex

	dh := DHCPServiceInfoMap[ifName]
	d := DHCPTemplate{
		DhcpInterface:   dh.BindInterface,
		IPAddressRanges: dh.NetworkSegment,
		DefaultGateway:  dh.DefaultGateway,
		NameServers:     dh.NameServers,
		Hostname:        dh.Hostname,
		LeaseTime:       86400,
	}
	var randomIP net.IP

	// 确定网段范围
	ip, ipNet, err := net.ParseCIDR(d.IPAddressRanges)
	if err != nil {
		global.Log.Error(err, "解析网段失败")
		return model.DHCP{}, err
	}
	if v, ok := recordMac[mac]; !ok {
		network := ip.Mask(ipNet.Mask)
		minIP := network.To4()
		maxIP := net.IPv4(minIP[0]|^ipNet.Mask[0],
			minIP[1]|^ipNet.Mask[1], minIP[2]|^ipNet.Mask[2],
			minIP[3]|^ipNet.Mask[3]).To4()
		// 生成随机种子
		rand.NewSource(time.Now().UnixNano())
		for {
			randomIP = generateRandomIP(minIP, maxIP)
			if _, ok := record[randomIP.String()]; !ok {
				m.Lock()
				record[randomIP.String()] = struct{}{}
				recordMac[mac] = randomIP.String()
				m.Unlock()
				break
			}
		}
	} else {
		randomIP = net.ParseIP(v)
	}

	// 构建DHCP信息
	subnetMask := strconv.Itoa(int(ipNet.Mask[0])) + "." + strconv.Itoa(int(ipNet.Mask[1])) + "." + strconv.Itoa(int(ipNet.Mask[2])) + "." + strconv.Itoa(int(ipNet.Mask[3]))
	dhcp := buildDHCP(randomIP.String(), subnetMask, mac, d)

	_ = dao.AddDHCP(dhcp)

	return dhcp, err
}

func generateRandomIP(min, max net.IP) net.IP {
	// IP地址是32位的，每位都是一个字节
	ip := make(net.IP, len(min))
	for i := range min {
		n := int(max[i] - min[i])
		if n == 0 {
			ip[i] = min[i]
		} else {
			ip[i] = byte(rand.Intn(n) + int(min[i]))
		}
	}
	if ip.Equal(min) || ip.Equal(max) {
		return generateRandomIP(min, max)
	}
	return ip
}

func buildDHCP(randomIP string, subnetMask, mac string, d DHCPTemplate) model.DHCP {

	ipinfo := model.DHCP{
		Interface:        d.DhcpInterface,
		MACAddress:       mac,
		IPAddress:        randomIP,
		SubnetMask:       subnetMask,
		DefaultGateway:   d.DefaultGateway,
		NameServers:      d.NameServers,
		DomainName:       d.DomainName,
		BroadcastAddress: d.BroadcastAddress,
		NTPServers:       d.NTPServers,
		VLANID:           d.VLANID,
		LeaseTime:        uint32(d.LeaseTime),
		DomainSearch:     d.DomainSearch,
	}
	return ipinfo
}

func isIPInSubnet(ip, ifName string) bool {
	// Parse the IP address
	ipAddr := net.ParseIP(ip)
	if ipAddr == nil {
		return false
	}

	// Parse the subnet
	_, ipNet, err := net.ParseCIDR(DHCPServiceInfoMap[ifName].NetworkSegment)
	if err != nil {
		return false
	}

	// Check if the IP address is in the subnet
	return ipNet.Contains(ipAddr)
}
