//go:build with_gvisor

package tailscale

import (
	"context"
	"net/netip"
	"time"

	"github.com/sagernet/sing-box/adapter"
	"github.com/sagernet/tailscale/ipn/ipnstate"
	"github.com/sagernet/tailscale/tailcfg"
)

func (t *Endpoint) StartTailscalePing(ctx context.Context, peerIP string, fn func(*adapter.TailscalePingResult)) error {
	ip, err := netip.ParseAddr(peerIP)
	if err != nil {
		return err
	}
	localClient, err := t.server.LocalClient()
	if err != nil {
		return err
	}
	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()
	for {
		result, pingErr := localClient.Ping(ctx, ip, tailcfg.PingDisco)
		if ctx.Err() != nil {
			return ctx.Err()
		}
		if pingErr != nil {
			fn(&adapter.TailscalePingResult{
				Error: pingErr.Error(),
			})
		} else {
			fn(convertPingResult(result))
		}
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ticker.C:
		}
	}
}

func convertPingResult(result *ipnstate.PingResult) *adapter.TailscalePingResult {
	return &adapter.TailscalePingResult{
		LatencyMs:      result.LatencySeconds * 1000,
		IsDirect:       result.Endpoint != "",
		Endpoint:       result.Endpoint,
		PeerRelay:      result.PeerRelay,
		DERPRegionID:   int32(result.DERPRegionID),
		DERPRegionCode: result.DERPRegionCode,
		Error:          result.Err,
	}
}
