package osrouter

import (
	"net/netip"

	"tailscale.com/net/tsaddr"
)

// selectRouteGateway returns the nexthop to use for a Windows route and whether
// the route should be skipped because it is the interface's own address.
//
// Official newer Windows routing prefers the Tailscale service IP as the
// nexthop for non-single-IP routes so they are not treated as on-link. That is
// useful for generic advertised LAN subnets, but it regresses Mirage's exit
// node path on some networks. For exit defaults and Tailscale-internal ranges,
// keep the older on-link behaviour.
func selectRouteGateway(route netip.Prefix, localAddr, serviceAddr netip.Addr) (gateway netip.Addr, skip bool) {
	destAddr := route.Addr().Unmap()
	if destAddr == localAddr.Unmap() {
		return netip.Addr{}, true
	}

	switch {
	case route.Bits() == 0:
		return localAddr, false
	case route == tsaddr.CGNATRange():
		return localAddr, false
	case route == tsaddr.TailscaleULARange():
		return localAddr, false
	case route.IsSingleIP() && (destAddr == serviceAddr.Unmap() || tsaddr.IsTailscaleIP(destAddr)):
		return localAddr, false
	default:
		return serviceAddr, false
	}
}
