package osrouter

import (
	"net/netip"
	"testing"

	"tailscale.com/net/tsaddr"
)

func TestSelectRouteGateway(t *testing.T) {
	local4 := netip.MustParseAddr("100.64.0.7")
	service4 := tsaddr.TailscaleServiceIP()
	local6 := netip.MustParseAddr("fd7a:115c:a1e0::7")
	service6 := tsaddr.TailscaleServiceIPv6()

	tests := []struct {
		name        string
		route       netip.Prefix
		localAddr   netip.Addr
		serviceAddr netip.Addr
		want        netip.Addr
		wantSkip    bool
	}{
		{
			name:        "skip own v4 address",
			route:       netip.PrefixFrom(local4, 32),
			localAddr:   local4,
			serviceAddr: service4,
			wantSkip:    true,
		},
		{
			name:        "default v4 route stays on link",
			route:       tsaddr.AllIPv4(),
			localAddr:   local4,
			serviceAddr: service4,
			want:        local4,
		},
		{
			name:        "default v6 route stays on link",
			route:       tsaddr.AllIPv6(),
			localAddr:   local6,
			serviceAddr: service6,
			want:        local6,
		},
		{
			name:        "cgnat aggregate stays on link",
			route:       tsaddr.CGNATRange(),
			localAddr:   local4,
			serviceAddr: service4,
			want:        local4,
		},
		{
			name:        "tailscale ula aggregate stays on link",
			route:       tsaddr.TailscaleULARange(),
			localAddr:   local6,
			serviceAddr: service6,
			want:        local6,
		},
		{
			name:        "single tailscale ip stays on link",
			route:       netip.MustParsePrefix("100.64.0.8/32"),
			localAddr:   local4,
			serviceAddr: service4,
			want:        local4,
		},
		{
			name:        "generic subnet still uses service gateway",
			route:       netip.MustParsePrefix("192.168.0.0/24"),
			localAddr:   local4,
			serviceAddr: service4,
			want:        service4,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, gotSkip := selectRouteGateway(tt.route, tt.localAddr, tt.serviceAddr)
			if gotSkip != tt.wantSkip {
				t.Fatalf("skip = %v, want %v", gotSkip, tt.wantSkip)
			}
			if got != tt.want {
				t.Fatalf("gateway = %v, want %v", got, tt.want)
			}
		})
	}
}
