package mcp

import (
	"net"
	"testing"
)

func TestIsBlockedIP(t *testing.T) {
	blocked := []string{"127.0.0.1", "10.1.2.3", "172.16.0.5", "192.168.1.1", "169.254.169.254", "0.0.0.0", "::1"}
	for _, s := range blocked {
		if !isBlockedIP(net.ParseIP(s)) {
			t.Errorf("%s 应被拦截（内网/环回/元数据）", s)
		}
	}
	allowed := []string{"8.8.8.8", "1.1.1.1", "93.184.216.34"}
	for _, s := range allowed {
		if isBlockedIP(net.ParseIP(s)) {
			t.Errorf("%s 是公网，不应被拦截", s)
		}
	}
}

func TestValidateExternalURL_Scheme(t *testing.T) {
	for _, raw := range []string{"ftp://x/y", "file:///etc/passwd", "not a url", "ws://h"} {
		if reason, ok := validateExternalURL(raw, nil); ok {
			t.Errorf("%q 应被拒（非 http/https）, got ok reason=%q", raw, reason)
		}
	}
}

func TestValidateExternalURL_SSRF(t *testing.T) {
	// 字面量 IP 不走真实 DNS，可离线判定。
	for _, raw := range []string{"http://127.0.0.1/admin", "http://169.254.169.254/latest/meta-data/", "http://10.0.0.1/"} {
		if _, ok := validateExternalURL(raw, nil); ok {
			t.Errorf("%q 应被 SSRF 防护拦截", raw)
		}
	}
	// 公网字面量放行。
	if reason, ok := validateExternalURL("http://8.8.8.8/", nil); !ok {
		t.Errorf("公网 IP 应放行, got %q", reason)
	}
}

func TestValidateExternalURL_Allowlist(t *testing.T) {
	allow := []string{"api.github.com"}
	if _, ok := validateExternalURL("http://8.8.8.8/", allow); ok {
		t.Error("白名单生效时，非白名单主机应被拒")
	}
	if !hostAllowed("api.github.com", allow) || !hostAllowed("sub.api.github.com", allow) {
		t.Error("白名单主机及其子域应放行")
	}
	if hostAllowed("evil.com", allow) {
		t.Error("非白名单主机不应放行")
	}
}
