package services

import "testing"

func TestClientIPTrustsForwardedHeadersByDefault(t *testing.T) {
	ip := ClientIP("127.0.0.1:6070", "203.0.113.10, 10.0.0.2", "198.51.100.2", nil)
	if ip != "203.0.113.10" {
		t.Fatalf("ClientIP = %q, want forwarded IP", ip)
	}
}

func TestClientIPUsesTrustedProxyCIDRs(t *testing.T) {
	trusted := []string{"127.0.0.1", "172.16.0.0/12"}
	ip := ClientIP("172.20.0.4:6070", "203.0.113.11", "", trusted)
	if ip != "203.0.113.11" {
		t.Fatalf("trusted ClientIP = %q", ip)
	}
	spoofed := ClientIP("198.51.100.20:6070", "203.0.113.12", "203.0.113.13", trusted)
	if spoofed != "198.51.100.20" {
		t.Fatalf("untrusted ClientIP = %q, want remote addr", spoofed)
	}
}

func TestClientIPFallsBackToRealIP(t *testing.T) {
	ip := ClientIP("127.0.0.1:6070", "", "203.0.113.14", nil)
	if ip != "203.0.113.14" {
		t.Fatalf("ClientIP = %q, want real IP", ip)
	}
}

func TestClientIPStripsPortsFromForwardedHeaders(t *testing.T) {
	ip := ClientIP("127.0.0.1:6070", "203.0.113.15:49152", "", nil)
	if ip != "203.0.113.15" {
		t.Fatalf("ClientIP = %q, want forwarded IP without port", ip)
	}
}

func TestClientIPPrefersExternalForwardedAddress(t *testing.T) {
	ip := ClientIP("127.0.0.1:6070", "172.30.0.1, 198.51.100.30", "", nil)
	if ip != "198.51.100.30" {
		t.Fatalf("ClientIP = %q, want public forwarded IP", ip)
	}
}

func TestIPOnlyHandlesIPv6HostPort(t *testing.T) {
	ip := IPOnly("[2001:db8::1]:6070")
	if ip != "2001:db8::1" {
		t.Fatalf("IPOnly = %q, want IPv6 address without port", ip)
	}
}

func TestProtectedProxyIP(t *testing.T) {
	trusted := []string{"127.0.0.1", "172.30.0.1", "10.88.0.0/16"}
	for _, ip := range []string{"127.0.0.1:48122", "172.30.0.1", "10.88.0.12"} {
		if !IsProtectedProxyIP(ip, trusted) {
			t.Fatalf("IsProtectedProxyIP(%q) = false, want true", ip)
		}
	}
	if IsProtectedProxyIP("203.0.113.50", trusted) {
		t.Fatalf("external IP treated as protected")
	}
}

func TestProtectedBanTarget(t *testing.T) {
	trusted := []string{"172.30.0.1", "10.88.0.0/16"}
	for _, target := range []string{"127.0.0.1", "172.30.0.1", "172.30.0.0/24", "10.88.12.0/24"} {
		if !ProtectedBanTarget(target, trusted) {
			t.Fatalf("ProtectedBanTarget(%q) = false, want true", target)
		}
	}
	if ProtectedBanTarget("203.0.113.0/24", trusted) {
		t.Fatalf("external target treated as protected")
	}
}
