package utils

import (
	"fmt"
	"gitee.ltd/lxh/logger/log"
	"github.com/spf13/cast"
	"net"
	"strings"
	"wireguard-ui/global/client"
)

type network struct{}

func Network() network {
	return network{}
}

// GetHostPublicIP
// @description: 获取本机公网地址
// @receiver network
// @return string
func (network) GetHostPublicIP() string {
	var response = map[string]string{}
	_, err := client.HttpClient.R().SetResult(&response).Get("https://httpbin.org/ip")
	if err != nil {
		log.Errorf("获取本机公网IP失败: %v", err.Error())
		return ""
	}

	return response["origin"]
}

// IPContains
// @description: 校验ip是否在指定IP段中
// @receiver network
// @param specIp
// @param checkIP
func (network) IPContains(specIp []string, checkIP string) bool {
	var isContains bool
	for _, sip := range specIp {
		ip, _, _ := net.ParseCIDR(checkIP)
		sipNet, _, _ := net.ParseCIDR(sip)
		ipNet := net.IPNet{IP: sipNet, Mask: net.CIDRMask(24, 32)}

		if ipNet.Contains(ip) {
			isContains = true
		}
	}

	return isContains
}

// IPContainsByIP
// @description: 校验ip是否在指定IP段中
// @receiver network
// @param specIp
// @param checkIP
func (network) IPContainsByIP(specIp string, checkIP string) bool {
	ip, _, _ := net.ParseCIDR(checkIP)
	sipNet, _, _ := net.ParseCIDR(specIp)
	ipNet := net.IPNet{IP: sipNet, Mask: net.CIDRMask(24, 32)}

	if ipNet.Contains(ip) {
		return true
	}
	return false
}

// ParseIP
// @description: 将带有mark的ip解析
// @receiver network
// @param ip
// @return string
func (network) ParseIP(ip string) string {
	ipn, _, _ := net.ParseCIDR(ip)
	return ipn.String()
}

// GetIPSuffix
// @description: 获取IP后缀 [10.10.10.23] 这里只获取23
// @receiver network
// @param ip
// @return string
func (network) GetIPSuffix(ip string) string {
	if strings.Contains(ip, "/") {
		ip = strings.Split(ip, "/")[0]
	}

	// 再次拆分，只取最后一段
	return strings.Split(ip, ".")[3]
}

// GetIPPrefix
// @description: 获取IP前缀[10.10.10.23] 这里只获取 10.10.10
// @receiver network
// @param ip
// @return string
func (network) GetIPPrefix(ip string) string {
	if strings.Contains(ip, "/") {
		ip = strings.Split(ip, "/")[0]
	}

	return strings.Join(strings.Split(ip, ".")[:3], ".")
}

// GenerateIPByIPS
// @description: 根据指定IP段分配IP
// @receiver n
// @param ips
// @param assignedIPS
// @return string
func (n network) GenerateIPByIPS(ips []string, assignedIPS ...string) []string {
	var oips []string
	for _, sip := range ips {
		// 再次拆分，只取最后一段
		suffix := n.GetIPSuffix(sip)
		prefix := n.GetIPPrefix(sip)
		for _, cip := range assignedIPS {
			if n.IPContainsByIP(sip, cip) {
				suffix = n.GetIPSuffix(cip)
			}
		}
		suffix = cast.ToString(cast.ToInt64(suffix) + 1)
		oips = append(oips, fmt.Sprintf("%s.%s/32", prefix, suffix))
	}

	return oips
}
