package runner

import (
	"testing"
	"time"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/executionpool"
	"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)

func TestNextRouteHealthRequiresFailuresAndRecoverySamples(t *testing.T) {
	now := time.Now()
	health := executionpool.RouteHealth{}
	for index := 0; index < 2; index++ {
		health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(time.Duration(index) * time.Second), ErrorClass: "network"})
		if health.State == executionpool.RouteUnreachable {
			t.Fatalf("became unreachable after %d failures", index+1)
		}
	}
	health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(2 * time.Second), ErrorClass: "network"})
	if health.State != executionpool.RouteUnreachable {
		t.Fatalf("state=%s, want unreachable", health.State)
	}
	health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(3 * time.Second), Reachable: true, TCPDuration: 5 * time.Millisecond, FirstByte: 20 * time.Millisecond})
	if health.State != executionpool.RouteDegraded {
		t.Fatalf("state=%s, want degraded during recovery", health.State)
	}
	health = nextRouteHealth(health, "pool", "route", executionpool.ProbeResult{SampledAt: now.Add(4 * time.Second), Reachable: true, TCPDuration: 5 * time.Millisecond, FirstByte: 20 * time.Millisecond})
	if health.State != executionpool.RouteHealthy {
		t.Fatalf("state=%s, want healthy", health.State)
	}
	if health.ExpiresAt.Sub(health.SampledAt) != 45*time.Second {
		t.Fatalf("health TTL=%s", health.ExpiresAt.Sub(health.SampledAt))
	}
}

func TestPinCandidatesToRoutingAssignment(t *testing.T) {
	candidates := []store.RuntimeModelCandidate{
		{PlatformID: "platform-a", PlatformModelID: "model-a"},
		{PlatformID: "platform-b", PlatformModelID: "model-b"},
	}
	pinned := pinCandidatesToRoutingAssignment(candidates, "platform-b", "model-b")
	if len(pinned) != 1 || pinned[0].PlatformModelID != "model-b" {
		t.Fatalf("pinned=%+v", pinned)
	}
	if got := pinCandidatesToRoutingAssignment(candidates, "platform-a", "missing"); len(got) != 0 {
		t.Fatalf("unexpected fallback: %+v", got)
	}
}
