package admin

import (
	"encoding/hex"
	"net"
	"strings"
	"testing"
)

func TestValidateListen_RejectsPublic(t *testing.T) {
	bad := []string{"0.0.0.0:9443", ":9443", "[::]:9443", "::"}
	for _, addr := range bad {
		if err := validateListen(addr); err == nil {
			t.Errorf("validateListen(%q) = nil; want error (public bind)", addr)
		}
	}
	good := []string{"127.0.0.1:9443", "10.0.0.5:9443", "192.168.1.2:9090", "internal.host:9443"}
	for _, addr := range good {
		if err := validateListen(addr); err != nil {
			t.Errorf("validateListen(%q) = %v; want nil", addr, err)
		}
	}
}

func TestParseSecretKey(t *testing.T) {
	key := make([]byte, 32)
	for i := range key {
		key[i] = byte(i)
	}
	if _, err := parseSecretKey(hex.EncodeToString(key)); err != nil {
		t.Errorf("hex key rejected: %v", err)
	}
	if _, err := parseSecretKey("short"); err == nil {
		t.Error("short key accepted")
	}
	if _, err := parseSecretKey(""); err == nil {
		t.Error("empty key accepted")
	}
}

func TestParseCIDRs_Defaults(t *testing.T) {
	nets, err := ParseCIDRs(defaultInternalCIDRs)
	if err != nil {
		t.Fatal(err)
	}
	// Loopback and an RFC1918 address must be inside; a public one must not.
	inside := []string{"127.0.0.1", "10.1.2.3", "192.168.0.9", "172.16.5.5"}
	for _, ip := range inside {
		if !anyContains(nets, ip) {
			t.Errorf("%s not covered by default allowlist", ip)
		}
	}
	if anyContains(nets, "8.8.8.8") {
		t.Error("public IP 8.8.8.8 unexpectedly allowed")
	}
}

func TestParseCIDRs_BareIP(t *testing.T) {
	nets, err := ParseCIDRs([]string{"203.0.113.7"})
	if err != nil {
		t.Fatal(err)
	}
	if !anyContains(nets, "203.0.113.7") {
		t.Error("bare IP host route not matched")
	}
	if anyContains(nets, "203.0.113.8") {
		t.Error("bare IP matched neighbour")
	}
}

func TestParseCIDRs_Invalid(t *testing.T) {
	if _, err := ParseCIDRs([]string{"not-a-cidr"}); err == nil {
		t.Error("invalid CIDR accepted")
	}
	if _, err := ParseCIDRs(nil); err == nil {
		t.Error("empty allowlist accepted")
	}
}

func anyContains(nets []*net.IPNet, ip string) bool {
	parsed := net.ParseIP(ip)
	for _, n := range nets {
		if n.Contains(parsed) {
			return true
		}
	}
	return false
}

func TestSplitTrim(t *testing.T) {
	got := splitTrim(" a , b ,, c ")
	if strings.Join(got, ",") != "a,b,c" {
		t.Errorf("splitTrim = %v", got)
	}
}
