package netsplit

import (
	`io/fs`
	`net/netip`
	`sync`

	`github.com/go-resty/resty/v2`
)

const (
	maxBitsv4 uint8 = 32
	maxBitsv6 uint8 = 128
	maxBits   uint8 = maxBitsv6
)

const (
	cachedirEnvName string = "SBNTR_RSVCACHE_DIR"
	// https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
	ianaSpecial4 string = "https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xml"
	// https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
	ianaSpecial6      string      = "https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xml"
	ianaDateTfmt      string      = "2006-01-02"
	ianaMonthTfmt     string      = "2006-01"
	ianaTrue          string      = "True"
	ianaFalse         string      = "False"
	ianaNA            string      = "N/A"
	ianaSpecial4Cache string      = "iana_reserved_4.json"
	ianaSpecial6Cache string      = "iana_reserved_6.json"
	cacheDirPerms     fs.FileMode = 0o0750
	cacheFilePerms    fs.FileMode = 0o0640
)

var (
	cacheDir      string
	isCaching     bool
	ianaReserved4 *IANARegistry
	ianaReserved6 *IANARegistry
)

var (
	// TODO
	cacheLock   sync.RWMutex
	cacheClient *resty.Client
	// IPv4: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml#iana-ipv4-special-registry-1
	// IPv6: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
	reservedNets map[netip.Prefix]*IANAAddrNetResRecord
	// Up to date as of Feb 2, 2025
	reservedNetsOrig map[string]string = map[string]string{
		// IPv6: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
		"::/128":            "Unspecified Address (RFC 4291 § 2.5.2)",
		"::1/128":           "Loopback Address (RFC 4291 § 2.5.3)",
		"ff00::/8":          "Multicast (RFC 4291 § 2.7)",
		"::ffff:0:0/96":     "IPv4-mapped Address (RFC 4291 § 2.5.5)",
		"64:ff9b::/96":      "IPv4-IPv6 Translation (RFC 6052)",
		"64:ff9b:1::/48":    "IPv4-IPv6 Translation (RFC 8215)",
		"100::/64":          "Discard-Only Address Block (RFC 6666)",
		"2001::/23":         "IETF Protocol Assignments (RFC 2928, IANA IPv6 Special Registry)",
		"2001::/32":         "TEREDO (RFC 4380)",
		"2001:1::1/128":     "Port Control Protocol Anycast (RFC 7723)",
		"2001:1::2/128":     "Traversal Using Relays around NAT Anycast (RFC 8155)",
		"2001:1::3/128":     "DNS-SD Service Registration Protocol Anycast (draft-ietf-dnssd-srp-25)",
		"2001:2::/48":       "Benchmarking (RFC 5180, Errata 1752)",
		"2001:3::/32":       "AMT (RFC 7450)",
		"2001:4:112::/48":   "AS112-v6 (RFC 7535)",
		"2001:20::/28":      "ORCHIDv2 (RFC 7343)",
		"2001:30::/28":      "Drone Remote ID Protocol Entity Tags (DETs) Prefix (RFC 9374)",
		"2001:db8::/32":     "Documentation (RFC 3849)",
		"2002::/16":         "6to4 (RFC 3056)",
		"2620:4f:8000::/48": "Direct Delegation AS112 Service (RFC 7534)",
		"3fff::/20":         "Documentation (RFC 9637)",
		"5f00::/16":         "Segment Routing (SRv6) SIDs (RFC 9602)",
		"fc00::/7":          "Unique-Local Addressing (RFC 4193)", // private/LAN
		"fe80::/10":         "Link-Local Unicast (RFC 4291 § 2.5.6)",
		// IPv4: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml#iana-ipv4-special-registry-1
		"0.0.0.0/8":          "\"This Network\" (RFC 791 § 3.2)",
		"0.0.0.0/32":         "\"This Host on This Network\" (RFC 1122 § 3.2.1.3)",
		"10.0.0.0/8":         "Private Use (RFC 1918)", // private/LAN
		"100.64.0.0/10":      "Shared Address Space (CGNAT) (RFC 6598)",
		"127.0.0.0/8":        "Loopback (RFC 1122 § 3.2.1.3)",
		"169.254.0.0/16":     "Link-Local (RFC 3927)",
		"172.16.0.0/12":      "Private Use (RFC 1918)", // private/LAN
		"192.0.0.0/24":       "IETF Protocol Assignments (RFC 6890 § 2.1)",
		"192.0.0.0/29":       "IPv4 Service Community Prefix (RFC 7335)",
		"192.0.0.8/32":       "IPv4 Dummy Address (RFC 7600)",
		"192.0.0.9/32":       "Port Control Protocol Anycast (RFC 7723)",
		"192.0.0.10/32":      "Traversal Using Relays Around NAT Anycast (RFC 8155)",
		"192.0.0.170/32":     "NAT64/DNS64 Discovery (RFC 7050 § 2.2) (RFC 8880)",
		"192.0.0.171/32":     "NAT64/DNS64 Discovery (RFC 7050 § 2.2) (RFC 8880)",
		"192.0.2.0/24":       "Documentation (TEST-NET-1) (RFC 5737)",
		"192.31.196.0/24":    "AS112-v4 (RFC 7535)",
		"192.52.193.0/24":    "AMT (RFC 7450)",
		"192.168.0.0/16":     "Private Use (RFC 1918)", // private/LAN
		"192.175.48.0/24":    "Direct Delegation AS112 Service (RFC 7534)",
		"198.18.0.0/15":      "Benchmarking (RFC 2544)",
		"198.51.100.0/24":    "Documentation (TEST-NET-2) (RFC 5737)",
		"240.0.0.0/24":       "Reserved for Future Use (RFC 1112 § 4)",
		"255.255.255.255/32": "Limited Broadcast (RFC 919 § 7) (RFC 8190)",
	}
)