package main

import (
	"context"
	"flag"
	"fmt"
	"net"
	"strings"
	"time"
)

// 判断IPv6 地址类型
func classifyIPv6(ip net.IP) string {
	if ip.IsLoopback() {
		return "Loopback"
	} else if ip.IsLinkLocalUnicast() {
		return "Link-Local"
	} else if ip.IsGlobalUnicast() {
		return "Global"
	}
	return "Unknown"
}

// getIPv6Addresses 获取网络接口的 IPv6 地址。
// 它会跳过回环接口，并且只考虑已启用的接口。
func getIPv6Addresses() (map[string][]net.IP, error) {
	// 创建一个 map 用于存储接口名称及其对应的 IPv6 地址。
	addresses := make(map[string][]net.IP)

	// 获取系统上的所有网络接口。
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil, err // 如果无法获取接口信息，则返回错误。
	}

	// 遍历所有网络接口。
	for _, iface := range interfaces {
		// 跳过未启用的接口或回环接口。
		if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
			continue
		}

		// 获取与该接口关联的地址。
		addrs, err := iface.Addrs()
		if err != nil {
			return nil, err // 如果无法获取地址，则返回错误。
		}

		// 遍历该接口的所有地址。
		for _, addr := range addrs {
			var ip net.IP
			switch v := addr.(type) {
			case *net.IPNet:
				ip = v.IP // 从 IPNet 类型中提取 IP。
			case *net.IPAddr:
				ip = v.IP // 从 IPAddr 类型中提取 IP。
			}

			// 检查 IP 是否为 IPv6 地址（即不是 IPv4）。
			if ip != nil && ip.To4() == nil {
				// 将 IPv6 地址添加到对应的接口名称列表中。
				addresses[iface.Name] = append(addresses[iface.Name], ip)
			}
		}
	}

	return addresses, nil // 返回包含 IPv6 地址的映射。
}

// 获取指定接口的 IPv6 地址
func pppoe_interface_ipv6(_interface string) string {
	addresses, err := getIPv6Addresses()
	if err != nil {
		fmt.Printf("获取 IPv6 地址失败: %v\n", err)
		return "NULL"
	}

	//fmt.Println("IPv6 地址列表:")
	for iface, ips := range addresses {
		//fmt.Printf("Interface: %s\n", iface)
		if iface == _interface {
			for _, ip := range ips {
				addrType := classifyIPv6(ip)

				if addrType == "Global" {

					return ip.String()
				}
			}

		}
	}

	return "NULL"
}

// 使用指定的 DNS 服务器解析域名的 IPv6 地址
func check_domain_ipv6(domain string) string {
	// 自定义解析器，使用 8.8.8.8 作为 DNS 服务器
	resolver := &net.Resolver{
		PreferGo: true,
		Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
			d := net.Dialer{
				Timeout: time.Second * 5,
			}
			return d.DialContext(ctx, "udp", "8.8.8.8:53") // 指定 Google DNS
		},
	}

	// 查询域名的 IP 地址
	ips, err := resolver.LookupIP(context.Background(), "ip6", domain)
	if err != nil {
		return "NULL"
	}

	// 遍历返回的 IP 地址，返回第一个 IPv6 地址
	for _, ip := range ips {
		if ip.To4() == nil {
			return ip.String()
		}
	}

	return "NULL"
}

// 循环获取域名解析地址和当前地址，并判断是否需要更新域名解析地址
func Loop() {

	var Domain_ipv6_addr string
	var Now_ipv6_addr string
	var Domain = "aixiao.me"     // 主域名
	var _interface = "pppoe-wan" // openwrt 网卡

	key := "28b94fdd541d213de7bcaef" // 你的 API Key
	Subdomain := "v6.aixiao.me"      // 你要获取的特定子域名

	Domain_ipv6_addr = check_domain_ipv6(Subdomain)
	Now_ipv6_addr = pppoe_interface_ipv6(_interface)

	if Now_ipv6_addr != Domain_ipv6_addr {
		fmt.Printf("域名解析地址: %s\n", Domain_ipv6_addr)
		fmt.Printf("当前地址: %s\n", Now_ipv6_addr)
		fmt.Printf("域名解析地址与现在地址不相等！！！\n")

		RecordID := FetchSubdomainRecord(key, Domain, Subdomain)
		fmt.Printf("RecordID:%s\n", RecordID)
		if RecordID != "NULL" {
			rrid := RecordID
			rrhost := strings.Split(Subdomain, ".")[0] // 获取子域名前缀 v6
			rrvalue := Now_ipv6_addr

			r := ProcessDNSUpdateForDomain(key, Domain, rrid, rrhost, rrvalue)
			if r == 1 {

			}
		}
	} else {
		fmt.Printf("域名解析地址: %s\n", Domain_ipv6_addr)
		fmt.Printf("当前地址: %s\n", Now_ipv6_addr)
		fmt.Printf("域名解析地址与现在地址相等，无需处理！！！\n")
	}

}

// Sleep 函数
func Sleep(m int) {
	time.Sleep(time.Duration(m) * time.Minute)
}

func main() {
	daemon := flag.Bool("d", false, "守护进程模式")
	flag.Parse()

	// 守护进程模式
	if *daemon {
		Daemon()
	}

	for {
		Loop()
		Sleep(15)
	}
}
