package openai

import (
	"context"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"net/http"
	"net/http/httptest"
	"strings"
	"sync"
	"testing"
	"time"

	"iop/apps/edge/internal/authprojection"
	edgeservice "iop/apps/edge/internal/service"
	"iop/packages/go/config"
	"iop/packages/go/streamgate"
	iop "iop/proto/gen/iop"
)

func makeTestProjection(gen uint64, now time.Time, ttl time.Duration, tokens map[string]string, routes map[string]authprojection.Route) *iop.PrincipalProjection {
	proj := &iop.PrincipalProjection{
		Generation:        gen,
		IssuedAtUnixNano:  now.UnixNano(),
		ExpiresAtUnixNano: now.Add(ttl).UnixNano(),
	}
	for rawToken, pRef := range tokens {
		digest := sha256.Sum256([]byte(rawToken))
		proj.Tokens = append(proj.Tokens, &iop.ProjectedPrincipalToken{
			TokenDigestSha256: hex.EncodeToString(digest[:]),
			PrincipalRef:      pRef,
			PrincipalAlias:    pRef + "-alias",
			TokenRef:          "tok-" + pRef,
			TokenRevision:     gen,
		})
	}
	for _, r := range routes {
		selector := r.ResourceSelector
		if selector == "" {
			selector = "default"
		}
		routeRev := r.RouteRevision
		if routeRev == 0 {
			routeRev = gen
		}
		credRev := r.CredentialRevision
		if credRev == 0 {
			credRev = gen
		}
		proj.Routes = append(proj.Routes, &iop.ProjectedPrincipalRoute{
			RouteId:            r.RouteID,
			RouteAlias:         r.RouteAlias,
			PrincipalRef:       r.PrincipalRef,
			CredentialSlotRef:  r.CredentialSlotRef,
			ProfileId:          r.ProfileID,
			UpstreamModel:      r.UpstreamModel,
			ResourceSelector:   selector,
			RouteRevision:      routeRev,
			CredentialRevision: credRev,
		})
	}
	return proj
}

func TestManagedModelsListIsPrincipalScoped(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })

	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
		"token-p2": "principal-2",
	}, map[string]authprojection.Route{
		"r1": {RouteID: "route-p1", RouteAlias: "model-p1", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
		"r2": {RouteID: "route-p2", PrincipalRef: "principal-2", CredentialSlotRef: "slot-2", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	srv := NewServer(config.EdgeOpenAIConf{
		Models: []string{"global-model"},
	}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)

	// Call for P1
	reqP1 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP1.Header.Set("Authorization", "Bearer token-p1")
	wP1 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP1, reqP1)
	if wP1.Code != http.StatusOK {
		t.Fatalf("P1 status: %d body: %s", wP1.Code, wP1.Body.String())
	}
	var respP1 openAIModelsResponse
	if err := json.Unmarshal(wP1.Body.Bytes(), &respP1); err != nil {
		t.Fatal(err)
	}
	if len(respP1.Data) != 1 || respP1.Data[0].ID != "model-p1" {
		t.Fatalf("P1 models: expected public alias [model-p1], got %+v", respP1.Data)
	}

	// Call for P2
	reqP2 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP2.Header.Set("Authorization", "Bearer token-p2")
	wP2 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP2, reqP2)
	if wP2.Code != http.StatusOK {
		t.Fatalf("P2 status: %d body: %s", wP2.Code, wP2.Body.String())
	}
	var respP2 openAIModelsResponse
	if err := json.Unmarshal(wP2.Body.Bytes(), &respP2); err != nil {
		t.Fatal(err)
	}
	if len(respP2.Data) != 1 || respP2.Data[0].ID != "route-p2" {
		t.Fatalf("P2 models: expected [route-p2], got %+v", respP2.Data)
	}
}

func TestManagedAnthropicModelsListUsesRouteIDs(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {RouteID: "claude-route-1", RouteAlias: "claude-public-1", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "anthropic", UpstreamModel: "claude-3-5-sonnet", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)

	req := httptest.NewRequest(http.MethodGet, "/anthropic/v1/models", nil)
	req.Header.Set("Authorization", "Bearer token-p1")
	req.Header.Set("anthropic-version", "2023-06-01")
	w := httptest.NewRecorder()
	srv.routes().ServeHTTP(w, req)
	if w.Code != http.StatusOK {
		t.Fatalf("status: %d body: %s", w.Code, w.Body.String())
	}
	var anthropicResp struct {
		Data []struct {
			ID string `json:"id"`
		} `json:"data"`
	}
	if err := json.Unmarshal(w.Body.Bytes(), &anthropicResp); err != nil {
		t.Fatal(err)
	}
	if len(anthropicResp.Data) != 1 || anthropicResp.Data[0].ID != "claude-public-1" {
		t.Fatalf("expected public alias [claude-public-1], got %+v", anthropicResp.Data)
	}
}

func TestManagedModelsOmitInactiveRoutes(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	proj1 := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {RouteID: "route-1", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj1); err != nil {
		t.Fatal(err)
	}

	srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)

	// Gen 2 removes route-1
	proj2 := makeTestProjection(2, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, nil)
	if err := cache.Apply(proj2); err != nil {
		t.Fatal(err)
	}

	req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	req.Header.Set("Authorization", "Bearer token-p1")
	w := httptest.NewRecorder()
	srv.routes().ServeHTTP(w, req)
	if w.Code != http.StatusOK {
		t.Fatalf("status: %d body: %s", w.Code, w.Body.String())
	}
	var resp openAIModelsResponse
	if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
		t.Fatal(err)
	}
	if len(resp.Data) != 0 {
		t.Fatalf("expected 0 models for omitted route, got %+v", resp.Data)
	}
}

func TestUnmanagedModelsRetainGlobalCatalog(t *testing.T) {
	srv := NewServer(config.EdgeOpenAIConf{
		Models: []string{"global-model-1", "global-model-2"},
	}, &fakeRunService{}, nil)

	req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	w := httptest.NewRecorder()
	srv.routes().ServeHTTP(w, req)
	if w.Code != http.StatusOK {
		t.Fatalf("status: %d body: %s", w.Code, w.Body.String())
	}
	var resp openAIModelsResponse
	if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
		t.Fatal(err)
	}
	if len(resp.Data) != 2 {
		t.Fatalf("expected 2 global models, got %d", len(resp.Data))
	}
}

func TestManagedRouteSelectsOnlyBoundSlot(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {
			RouteID:           "bound-route",
			PrincipalRef:      "principal-1",
			CredentialSlotRef: "slot-bound",
			ProfileID:         "profile-bound",
			UpstreamModel:     "model-bound",
			ResourceSelector:  "default",
		},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)
	srv.SetModelCatalog([]config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "model-bound"}}})

	req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
	req.Header.Set("Authorization", "Bearer token-p1")
	principal, view, ok := srv.authenticatePrincipal(req)
	if !ok {
		t.Fatal("managed authentication failed")
	}
	ctx := withAuthenticatedProjectionView(withPrincipal(req.Context(), principal), view)

	disp, err := srv.resolveRouteDispatchForPrincipal(ctx, "bound-route")
	if err != nil {
		t.Fatalf("resolveRouteDispatchForPrincipal failed: %v", err)
	}
	if !disp.Managed || disp.CredentialSlotRef != "slot-bound" || disp.ModelGroupKey != "catalog-internal" {
		t.Fatalf("unexpected dispatch: %+v", disp)
	}

	pred := disp.CandidatePredicate()
	if pred == nil {
		t.Fatalf("expected non-nil CandidatePredicate")
	}

	// Correct candidate
	validCandidate := edgeservice.ProviderPoolCandidate{
		ProviderID:    "provider-resource",
		ProfileID:     "profile-bound",
		ActualModel:   "model-bound",
		ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
	}
	if !pred(validCandidate) {
		t.Fatalf("pred rejected valid candidate")
	}

	// A default selector does not confuse credential slot identity with a
	// provider resource restriction.
	otherResource := validCandidate
	otherResource.ProviderID = "another-provider"
	if !pred(otherResource) {
		t.Fatalf("default selector unexpectedly restricted provider resource")
	}

	// Mismatched profile
	badProfile := validCandidate
	badProfile.ProfileID = "profile-other"
	if pred(badProfile) {
		t.Fatalf("pred accepted candidate with bad profile")
	}

	// Mismatched upstream model
	badModel := validCandidate
	badModel.ActualModel = "model-other"
	if pred(badModel) {
		t.Fatalf("pred accepted candidate with bad upstream model")
	}
}

func TestManagedRoutePredicateSurvivesRecovery(t *testing.T) {
	route := authprojection.Route{
		RouteID:           "r1",
		CredentialSlotRef: "slot-1",
		ProfileID:         "prof-1",
		UpstreamModel:     "mod-1",
	}
	pred := managedRouteCandidatePredicate(route, "provider-1")
	streamPred := func(c edgeservice.ProviderPoolCandidate) bool {
		return c.ExecutionPath == "provider_tunnel"
	}
	composed := composeCandidatePredicates(streamPred, pred)

	candGood := edgeservice.ProviderPoolCandidate{
		ProviderID:    "provider-1",
		ProfileID:     "prof-1",
		ActualModel:   "mod-1",
		ExecutionPath: "provider_tunnel",
	}
	candBadSlot := candGood
	candBadSlot.ProviderID = "provider-2"

	if !composed(candGood) {
		t.Fatalf("composed predicate rejected valid candidate")
	}
	if composed(candBadSlot) {
		t.Fatalf("composed predicate accepted mismatched slot")
	}
}

func TestManagedCatalogBindingExplicitSelectorAndNoFallback(t *testing.T) {
	route := authprojection.Route{UpstreamModel: "served", ResourceSelector: "provider-resource"}
	catalog := []config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served", "other": "served"}}}
	binding, err := resolveManagedCatalogBinding(route, catalog)
	if err != nil || binding.ModelGroupKey != "catalog-internal" || binding.ProviderID != "provider-resource" {
		t.Fatalf("binding=%+v err=%v", binding, err)
	}
	route.ResourceSelector = "default"
	binding, err = resolveManagedCatalogBinding(route, catalog)
	if err != nil || binding.ProviderID != "" {
		t.Fatalf("default binding=%+v err=%v", binding, err)
	}
	route.ResourceSelector = "missing"
	if _, err := resolveManagedCatalogBinding(route, catalog); !errors.Is(err, ErrRouteNotFound) {
		t.Fatalf("missing selector err=%v", err)
	}
	route.ResourceSelector = "default"
	ambiguous := append(catalog, config.ModelCatalogEntry{ID: "another-group", Providers: map[string]string{"provider-resource": "served"}})
	if _, err := resolveManagedCatalogBinding(route, ambiguous); !errors.Is(err, ErrRouteNotFound) {
		t.Fatalf("ambiguous catalog err=%v", err)
	}
	route.RouteAlias = "another-group"
	binding, err = resolveManagedCatalogBinding(route, ambiguous)
	if err != nil || binding.ModelGroupKey != "another-group" || binding.ProviderID != "" {
		t.Fatalf("alias-disambiguated binding=%+v err=%v", binding, err)
	}
}

func TestMetadataSpoofIsOverwrittenByManagedBinding(t *testing.T) {
	route := routeDispatch{Managed: true, RouteID: "route-public", CredentialSlotRef: "credential-slot", RouteRevision: 7, CredentialRevision: 11}
	req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
	req = req.WithContext(withPrincipal(req.Context(), openAIPrincipal{PrincipalRef: "principal", Source: principalSourceProjection}))
	metadata, err := resolveCallerIdentity(req, route, json.RawMessage(`{"iop_route_id":"spoof","iop_route_revision":"0","iop_credential_slot_ref":"spoof","iop_credential_revision":"0"}`))
	if err != nil {
		t.Fatal(err)
	}
	if metadata[routeMetaID] != "route-public" || metadata[routeMetaRevision] != "7" || metadata[credentialSlotMeta] != "credential-slot" || metadata[credentialRevisionMeta] != "11" {
		t.Fatalf("trusted metadata=%+v", metadata)
	}
}

func TestManagedProjectionFixturePreservesBindingFacts(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {
			RouteID:            "route-public",
			PrincipalRef:       "principal-1",
			CredentialSlotRef:  "credential-slot",
			ProfileID:          "openai",
			UpstreamModel:      "gpt-4o",
			ResourceSelector:   "provider-resource",
			RouteRevision:      4,
			CredentialRevision: 9,
		},
	})
	if len(proj.Routes) != 1 {
		t.Fatalf("expected 1 route, got %d", len(proj.Routes))
	}
	r := proj.Routes[0]
	if r.ResourceSelector != "provider-resource" {
		t.Errorf("ResourceSelector: got %q, want provider-resource", r.ResourceSelector)
	}
	if r.RouteRevision != 4 {
		t.Errorf("RouteRevision: got %d, want 4", r.RouteRevision)
	}
	if r.CredentialRevision != 9 {
		t.Errorf("CredentialRevision: got %d, want 9", r.CredentialRevision)
	}
}

func TestManagedSurfacesUseDistinctBinding(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	newManaged := func(route authprojection.Route, catalog config.ModelCatalogEntry, candidate edgeservice.ProviderPoolCandidate) (*Server, *providerFakeRunService) {
		cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
		proj := makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal"}, map[string]authprojection.Route{"route": route})
		if err := cache.Apply(proj); err != nil {
			t.Fatal(err)
		}
		fake := &providerFakeRunService{poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), poolSelectedCandidate: candidate}
		srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
		setManagedPrincipalProjection(srv, cache)
		srv.SetModelCatalog([]config.ModelCatalogEntry{catalog})
		return srv, fake
	}

	assertManagedTemplate := func(t *testing.T, group, provider string, meta map[string]string) {
		t.Helper()
		if group != "catalog-internal" {
			t.Fatalf("model group=%q, want catalog-internal", group)
		}
		if provider != "provider-resource" {
			t.Fatalf("provider=%q, want provider-resource", provider)
		}
		if meta[routeMetaID] != "route-public" || meta[routeMetaRevision] != "4" || meta[credentialSlotMeta] != "credential-slot" || meta[credentialRevisionMeta] != "9" {
			t.Fatalf("trusted metadata=%+v", meta)
		}
	}

	assertManagedBinding := func(t *testing.T, fake *providerFakeRunService) {
		t.Helper()
		run := fake.poolLastRunSnapshot()
		tunnels := fake.tunnelReqsSnapshot()
		if len(tunnels) != 1 {
			t.Fatalf("tunnel requests=%d, want 1", len(tunnels))
		}
		assertManagedTemplate(t, run.ModelGroupKey, run.ProviderID, run.Metadata)
		assertManagedTemplate(t, tunnels[0].ModelGroupKey, tunnels[0].ProviderID, tunnels[0].Metadata)
	}

	route := authprojection.Route{
		RouteID:            "route-public",
		PrincipalRef:       "principal",
		CredentialSlotRef:  "credential-slot",
		ProfileID:          "profile-openai",
		UpstreamModel:      "served-model",
		ResourceSelector:   "provider-resource",
		RouteRevision:      4,
		CredentialRevision: 9,
	}

	t.Run("chat", func(t *testing.T) {
		catalog := config.ModelCatalogEntry{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served-model"}}
		candidate := edgeservice.ProviderPoolCandidate{ProviderID: "provider-resource", ProfileID: "profile-openai", ActualModel: "served-model", ExecutionPath: string(edgeservice.ProviderPoolPathTunnel)}
		srv, fake := newManaged(route, catalog, candidate)
		fake.tunnelFrames = staticProviderTunnelFrames(`{"id":"chatcmpl-1","object":"chat.completion","model":"served-model","choices":[{"message":{"role":"assistant","content":"hi"}}]}`)
		req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{"model":"route-public","metadata":{"iop_route_id":"spoof","iop_route_revision":"0","iop_credential_slot_ref":"spoof","iop_credential_revision":"0"},"messages":[{"role":"user","content":"hi"}]}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		if !strings.Contains(w.Body.String(), `"model":"route-public"`) {
			t.Fatalf("body=%s, want model:route-public", w.Body.String())
		}
		assertManagedBinding(t, fake)
	})

	t.Run("responses", func(t *testing.T) {
		catalog := config.ModelCatalogEntry{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served-model"}}
		candidate := edgeservice.ProviderPoolCandidate{ProviderID: "provider-resource", ProfileID: "profile-openai", ActualModel: "served-model", ExecutionPath: string(edgeservice.ProviderPoolPathTunnel)}
		srv, fake := newManaged(route, catalog, candidate)
		req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{"model":"route-public","metadata":{"iop_route_id":"spoof","iop_route_revision":"0","iop_credential_slot_ref":"spoof","iop_credential_revision":"0"},"input":"hi"}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		assertManagedBinding(t, fake)
	})

	t.Run("messages", func(t *testing.T) {
		cand := anthropicTestCandidate(t, "anthropic")
		cand.ProviderID = "provider-resource"
		mRoute := authprojection.Route{
			RouteID:            "route-public",
			PrincipalRef:       "principal",
			CredentialSlotRef:  "credential-slot",
			ProfileID:          cand.ProfileID,
			UpstreamModel:      cand.ActualModel,
			ResourceSelector:   "provider-resource",
			RouteRevision:      4,
			CredentialRevision: 9,
		}
		catalog := config.ModelCatalogEntry{ID: "catalog-internal", Providers: map[string]string{"provider-resource": cand.ActualModel}}
		srv, fake := newManaged(mRoute, catalog, cand)
		fake.tunnelFrames = anthropicTunnelFrames(http.StatusOK, "application/json", mustReadAnthropicFixture(t, "native_message.json"))
		req := httptest.NewRequest(http.MethodPost, "/v1/messages", strings.NewReader(`{"model":"route-public","max_tokens":8,"messages":[{"role":"user","content":"hi"}]}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		assertManagedBinding(t, fake)
	})
}

func TestManagedCountTokensLocalAndNativeBinding(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	route := authprojection.Route{
		RouteID:            "route-public",
		PrincipalRef:       "principal",
		CredentialSlotRef:  "credential-slot",
		ProfileID:          "profile",
		UpstreamModel:      "served-model",
		ResourceSelector:   "provider-resource",
		RouteRevision:      4,
		CredentialRevision: 9,
	}

	t.Run("local counter", func(t *testing.T) {
		cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
		if err := cache.Apply(makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal"}, map[string]authprojection.Route{"route": route})); err != nil {
			t.Fatal(err)
		}
		fake := &providerFakeRunService{}
		srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
		setManagedPrincipalProjection(srv, cache)
		srv.SetModelCatalog([]config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "served-model"}, TokenCounter: &config.TokenCounterConf{Mode: config.TokenCounterDeterministic}}})

		req := httptest.NewRequest(http.MethodPost, "/v1/messages/count_tokens", strings.NewReader(`{"model":"route-public","messages":[{"role":"user","content":"hi"}]}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		if fake.poolSubmitCountSnapshot() != 0 {
			t.Fatalf("expected 0 pool dispatches for local counter, got %d", fake.poolSubmitCountSnapshot())
		}
	})

	t.Run("native provider-pool fallback", func(t *testing.T) {
		cand := anthropicTestCandidate(t, "anthropic")
		cand.ProviderID = "provider-resource"
		nativeRoute := route
		nativeRoute.ProfileID = cand.ProfileID
		nativeRoute.UpstreamModel = cand.ActualModel

		cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
		if err := cache.Apply(makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal"}, map[string]authprojection.Route{"route": nativeRoute})); err != nil {
			t.Fatal(err)
		}
		fake := &providerFakeRunService{poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel), poolSelectedCandidate: cand}
		fake.tunnelFrames = anthropicTunnelFrames(http.StatusOK, "application/json", []byte(`{"input_tokens":10}`))
		srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
		setManagedPrincipalProjection(srv, cache)
		srv.SetModelCatalog([]config.ModelCatalogEntry{{ID: "catalog-internal", Providers: map[string]string{"provider-resource": cand.ActualModel}}})

		req := httptest.NewRequest(http.MethodPost, "/v1/messages/count_tokens", strings.NewReader(`{"model":"route-public","messages":[{"role":"user","content":"hi"}]}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		if fake.poolSubmitCountSnapshot() != 1 {
			t.Fatalf("expected 1 pool dispatch for native counter, got %d", fake.poolSubmitCountSnapshot())
		}
		if fake.poolLastRun.ModelGroupKey != "catalog-internal" {
			t.Fatalf("model group=%q", fake.poolLastRun.ModelGroupKey)
		}
		meta := fake.poolLastRun.Metadata
		if meta[routeMetaID] != "route-public" || meta[routeMetaRevision] != "4" || meta[credentialSlotMeta] != "credential-slot" || meta[credentialRevisionMeta] != "9" {
			t.Fatalf("trusted metadata=%+v", meta)
		}
	})
}

type managedRecoveryRecorderService struct {
	fakeRunService
	mu             sync.Mutex
	submissions    []edgeservice.ProviderPoolDispatchRequest
	candidateOrder [][]edgeservice.ProviderPoolCandidate
}

func (s *managedRecoveryRecorderService) SubmitProviderPool(ctx context.Context, req edgeservice.ProviderPoolDispatchRequest) (*edgeservice.ProviderPoolDispatchResult, error) {
	s.mu.Lock()
	defer s.mu.Unlock()

	idx := len(s.submissions)
	s.submissions = append(s.submissions, req)

	var candidates []edgeservice.ProviderPoolCandidate
	if idx < len(s.candidateOrder) {
		candidates = s.candidateOrder[idx]
	}

	var accepted *edgeservice.ProviderPoolCandidate
	for i := range candidates {
		cand := candidates[i]
		if req.AcceptCandidate != nil {
			if req.AcceptCandidate(cand) {
				if accepted != nil {
					return nil, errors.New("multiple candidates accepted")
				}
				accepted = &cand
			}
		}
	}
	if accepted == nil {
		return nil, edgeservice.ErrProviderPoolCandidateRejected
	}

	disp := edgeservice.RunDispatch{
		RunID:         "run-recovery-" + accepted.ProviderID,
		NodeID:        "node-1",
		ModelGroupKey: req.Run.ModelGroupKey,
		Adapter:       "tunnel",
		Target:        accepted.ActualModel,
		ProviderID:    accepted.ProviderID,
		ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
	}
	handle := &fakeTunnelHandle{
		dispatch: disp,
		frames:   staticProviderTunnelFrames(`{"ok":true}`),
	}
	return &edgeservice.ProviderPoolDispatchResult{
		Path:         edgeservice.ProviderPoolPathTunnel,
		Tunnel:       handle,
		DispatchInfo: disp,
	}, nil
}

func TestManagedRecoveryReentersProviderPoolWithFrozenBinding(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {
			RouteID:            "bound-route",
			PrincipalRef:       "principal-1",
			CredentialSlotRef:  "slot-bound",
			ProfileID:          "profile-bound",
			UpstreamModel:      "model-bound",
			ResourceSelector:   "provider-resource",
			RouteRevision:      5,
			CredentialRevision: 12,
		},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	candValid := edgeservice.ProviderPoolCandidate{
		ProviderID:    "provider-resource",
		ProfileID:     "profile-bound",
		ActualModel:   "model-bound",
		ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
	}
	candWrongSlot := edgeservice.ProviderPoolCandidate{
		ProviderID:    "wrong-provider",
		ProfileID:     "profile-bound",
		ActualModel:   "model-bound",
		ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
	}
	candWrongProfile := edgeservice.ProviderPoolCandidate{
		ProviderID:    "provider-resource",
		ProfileID:     "wrong-profile",
		ActualModel:   "model-bound",
		ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
	}
	candWrongModel := edgeservice.ProviderPoolCandidate{
		ProviderID:    "provider-resource",
		ProfileID:     "profile-bound",
		ActualModel:   "wrong-model",
		ExecutionPath: string(edgeservice.ProviderPoolPathTunnel),
	}

	initialCandidates := []edgeservice.ProviderPoolCandidate{
		candWrongSlot, candWrongProfile, candWrongModel, candValid,
	}
	recoveryCandidates := []edgeservice.ProviderPoolCandidate{
		candWrongModel, candWrongProfile, candWrongSlot, candValid,
	}

	recorder := &managedRecoveryRecorderService{
		candidateOrder: [][]edgeservice.ProviderPoolCandidate{initialCandidates, recoveryCandidates},
	}

	srv := NewServer(config.EdgeOpenAIConf{}, recorder, nil)
	setManagedPrincipalProjection(srv, cache)
	srv.SetModelCatalog([]config.ModelCatalogEntry{
		{ID: "catalog-internal", Providers: map[string]string{"provider-resource": "model-bound"}},
	})

	req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{"model":"bound-route","metadata":{"iop_route_id":"spoof"},"messages":[{"role":"user","content":"hi"}]}`))
	req.Header.Set("Authorization", "Bearer token-p1")
	principal, view, ok := srv.authenticatePrincipal(req)
	if !ok {
		t.Fatal("authenticatePrincipal failed")
	}
	ctx := withAuthenticatedProjectionView(withPrincipal(req.Context(), principal), view)

	route, err := srv.resolveRouteDispatchForPrincipal(ctx, "bound-route")
	if err != nil {
		t.Fatalf("resolveRouteDispatchForPrincipal failed: %v", err)
	}

	runMeta, err := resolveCallerIdentity(req.WithContext(ctx), route, json.RawMessage(`{"iop_route_id":"spoof"}`))
	if err != nil {
		t.Fatalf("resolveCallerIdentity failed: %v", err)
	}
	requestCtx := openAIRequestContext{
		r:              req.WithContext(ctx),
		route:          route,
		callerMetadata: runMeta,
		usage:          srv.newOpenAIUsageRecorder(ctx, "bound-route", usageEndpointChatCompletions),
	}
	dc := srv.newChatDispatchContext(requestCtx, chatCompletionRequest{Model: "bound-route"}, "prompt", strictOutputPolicy{})

	initialPoolReq := edgeservice.ProviderPoolDispatchRequest{
		Run: dc.submitReq,
		Tunnel: edgeservice.SubmitProviderTunnelRequest{
			ModelGroupKey: dc.route.effectiveModelGroupKey("bound-route"),
			ProviderID:    dc.route.ProviderID,
			Method:        http.MethodPost,
			Path:          "/v1/chat/completions",
			Operation:     string(config.OperationChatCompletions),
			Metadata:      dc.runMetadata,
			ProviderPool:  true,
		},
	}
	if dc.route.Managed {
		initialPoolReq.AcceptCandidate = dc.route.CandidatePredicate()
	}

	res1, err := srv.service.SubmitProviderPool(ctx, initialPoolReq)
	if err != nil {
		t.Fatalf("initial SubmitProviderPool failed: %v", err)
	}
	if res1 == nil {
		t.Fatal("initial SubmitProviderPool returned nil result")
	}

	tunnelReq := openAITunnelStreamGateRequest{
		route:         route,
		method:        http.MethodPost,
		path:          "/v1/chat/completions",
		operation:     string(config.OperationChatCompletions),
		modelGroupKey: route.effectiveModelGroupKey("bound-route"),
		metadata:      dc.runMetadata,
		pool:          &initialPoolReq,
		rewriteBody: func(b []byte, target string) ([]byte, error) {
			return b, nil
		},
	}
	admissionBuilder := newOpenAITunnelRecoveryAdmissionBuilder(tunnelReq)
	recoveryAdmission, err := admissionBuilder(ctx, streamgate.RebuiltRequest{}, []byte(`{"model":"bound-route"}`))
	if err != nil {
		t.Fatalf("newOpenAITunnelRecoveryAdmissionBuilder failed: %v", err)
	}
	if recoveryAdmission.kind != openAIAdmissionPool {
		t.Fatalf("expected recovery admission kind openAIAdmissionPool, got %v", recoveryAdmission.kind)
	}

	res2, err := srv.service.SubmitProviderPool(ctx, recoveryAdmission.pool)
	if err != nil {
		t.Fatalf("recovery SubmitProviderPool failed: %v", err)
	}
	if res2 == nil {
		t.Fatal("recovery SubmitProviderPool returned nil result")
	}

	recorder.mu.Lock()
	subs := append([]edgeservice.ProviderPoolDispatchRequest(nil), recorder.submissions...)
	recorder.mu.Unlock()

	if len(subs) != 2 {
		t.Fatalf("expected 2 submissions to SubmitProviderPool, got %d", len(subs))
	}

	for i, sub := range subs {
		if sub.Run.ModelGroupKey != "catalog-internal" || sub.Tunnel.ModelGroupKey != "catalog-internal" {
			t.Errorf("submission %d: expected ModelGroupKey 'catalog-internal', got run=%q tunnel=%q", i, sub.Run.ModelGroupKey, sub.Tunnel.ModelGroupKey)
		}
		if sub.Run.Metadata[routeMetaID] != "bound-route" || sub.Run.Metadata[routeMetaRevision] != "5" || sub.Run.Metadata[credentialSlotMeta] != "slot-bound" || sub.Run.Metadata[credentialRevisionMeta] != "12" {
			t.Errorf("submission %d: Run trusted metadata mismatched: %+v", i, sub.Run.Metadata)
		}
		if sub.Tunnel.Metadata[routeMetaID] != "bound-route" || sub.Tunnel.Metadata[routeMetaRevision] != "5" || sub.Tunnel.Metadata[credentialSlotMeta] != "slot-bound" || sub.Tunnel.Metadata[credentialRevisionMeta] != "12" {
			t.Errorf("submission %d: Tunnel trusted metadata mismatched: %+v", i, sub.Tunnel.Metadata)
		}
		if !sub.AcceptCandidate(candValid) {
			t.Errorf("submission %d: rejected valid candidate", i)
		}
		if sub.AcceptCandidate(candWrongSlot) {
			t.Errorf("submission %d: accepted candidate with wrong slot/provider", i)
		}
		if sub.AcceptCandidate(candWrongProfile) {
			t.Errorf("submission %d: accepted candidate with wrong profile", i)
		}
		if sub.AcceptCandidate(candWrongModel) {
			t.Errorf("submission %d: accepted candidate with wrong model", i)
		}
	}
}

func TestGenerationSwapKeepsAuthenticatedRouteView(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	first := makeTestProjection(1, now, time.Hour, map[string]string{"token-p1": "principal-1"}, map[string]authprojection.Route{"r": {RouteID: "route-old", PrincipalRef: "principal-1", CredentialSlotRef: "slot", ProfileID: "profile", UpstreamModel: "served", ResourceSelector: "default"}})
	second := makeTestProjection(2, now, time.Hour, map[string]string{"token-p1": "principal-1"}, map[string]authprojection.Route{"r": {RouteID: "route-new", PrincipalRef: "principal-1", CredentialSlotRef: "slot", ProfileID: "profile", UpstreamModel: "served", ResourceSelector: "default"}})
	if err := cache.Apply(first); err != nil {
		t.Fatal(err)
	}
	srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)
	handler := srv.withAuth(func(w http.ResponseWriter, r *http.Request) {
		if err := cache.Apply(second); err != nil {
			t.Fatal(err)
		}
		models, err := srv.advertisedModelsForPrincipal(r.Context())
		if err != nil {
			t.Fatal(err)
		}
		if len(models) != 1 || models[0].ID != "route-old" {
			t.Fatalf("models after swap: %+v", models)
		}
		w.WriteHeader(http.StatusNoContent)
	})
	req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	req.Header.Set("Authorization", "Bearer token-p1")
	w := httptest.NewRecorder()
	handler(w, req)
	if w.Code != http.StatusNoContent {
		t.Fatalf("status=%d", w.Code)
	}
}

func TestManagedRouteFailureDoesNotFallback(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {RouteID: "known-route", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "prof-1", UpstreamModel: "mod-1", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	srv := NewServer(config.EdgeOpenAIConf{
		Target: "legacy-fallback-target",
		ModelRoutes: []config.OpenAIRouteEntry{
			{Model: "unmanaged-model", Target: "unmanaged-target"},
		},
	}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)

	req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
	req.Header.Set("Authorization", "Bearer token-p1")
	ctx := withPrincipal(req.Context(), openAIPrincipal{PrincipalRef: "principal-1", Source: principalSourceProjection})

	// Unknown route in managed mode
	_, err := srv.resolveRouteDispatchForPrincipal(ctx, "unmanaged-model")
	if err == nil {
		t.Fatalf("expected error resolving unmanaged-model in managed mode, got nil")
	}

	// Cross-principal route in managed mode
	_, err = srv.resolveRouteDispatchForPrincipal(ctx, "other-principal-route")
	if err == nil {
		t.Fatalf("expected error resolving cross-principal route, got nil")
	}
}

func TestManagedSurfacesTable(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"r1": {RouteID: "chat-route", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "openai", UpstreamModel: "gpt-4o", ResourceSelector: "default"},
		"r2": {RouteID: "messages-route", PrincipalRef: "principal-1", CredentialSlotRef: "slot-2", ProfileID: "anthropic", UpstreamModel: "claude-3", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	srv := NewServer(config.EdgeOpenAIConf{}, &fakeRunService{}, nil)
	setManagedPrincipalProjection(srv, cache)

	tests := []struct {
		name       string
		method     string
		path       string
		headers    map[string]string
		body       string
		wantStatus int
	}{
		{
			name:   "chat completion unknown route",
			method: http.MethodPost, path: "/v1/chat/completions",
			headers:    map[string]string{"Authorization": "Bearer token-p1"},
			body:       `{"model": "unknown-model", "messages": [{"role": "user", "content": "hi"}]}`,
			wantStatus: http.StatusBadRequest,
		},
		{
			name:   "responses unknown route",
			method: http.MethodPost, path: "/v1/responses",
			headers:    map[string]string{"Authorization": "Bearer token-p1"},
			body:       `{"model": "unknown-model", "input": "hi"}`,
			wantStatus: http.StatusBadRequest,
		},
		{
			name:   "anthropic messages unknown route",
			method: http.MethodPost, path: "/v1/messages",
			headers:    map[string]string{"Authorization": "Bearer token-p1", "anthropic-version": "2023-06-01"},
			body:       `{"model": "unknown-model", "max_tokens": 10, "messages": [{"role": "user", "content": "hi"}]}`,
			wantStatus: http.StatusBadRequest,
		},
		{
			name:   "anthropic count_tokens unknown route",
			method: http.MethodPost, path: "/v1/messages/count_tokens",
			headers:    map[string]string{"Authorization": "Bearer token-p1", "anthropic-version": "2023-06-01"},
			body:       `{"model": "unknown-model", "messages": [{"role": "user", "content": "hi"}]}`,
			wantStatus: http.StatusBadRequest,
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			req := httptest.NewRequest(tc.method, tc.path, strings.NewReader(tc.body))
			req.Header.Set("Content-Type", "application/json")
			for k, v := range tc.headers {
				req.Header.Set(k, v)
			}
			w := httptest.NewRecorder()
			srv.routes().ServeHTTP(w, req)
			if w.Code != tc.wantStatus {
				t.Fatalf("status: got %d, want %d body: %s", w.Code, tc.wantStatus, w.Body.String())
			}
		})
	}
}

func TestVirtualPresetModelAuthorizationMatrix(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })

	preset := config.ExecutionPreset{
		ID: "preset-multi-stage",
		Selector: config.ExecutionModelBinding{
			Model: "selector-model",
		},
		AllowedModes: []string{config.ModeLight},
		Routes: map[string]config.ExecutionRoute{
			config.ModeLight: {
				Stages: []config.ExecutionRouteStage{
					{Role: "local", Model: "local-model"},
					{Role: "review", Model: "review-model"},
				},
			},
		},
		WorkspaceTools: []config.ExecutionWorkspaceToolAlternative{
			{
				Name: "default",
				Operations: map[string]config.ExecutionWorkspaceOperation{
					"read":   {ToolName: "r", SchemaMatcher: map[string]any{"a": 1}, ArgumentMap: map[string]any{"a": 1}, ResultMatcher: map[string]any{"a": 1}},
					"write":  {ToolName: "w", SchemaMatcher: map[string]any{"a": 1}, ArgumentMap: map[string]any{"a": 1}, ResultMatcher: map[string]any{"a": 1}, CreatesParents: true},
					"delete": {ToolName: "d", SchemaMatcher: map[string]any{"a": 1}, ArgumentMap: map[string]any{"a": 1}, ResultMatcher: map[string]any{"a": 1}},
				},
			},
		},
	}

	catalog := []config.ModelCatalogEntry{
		{
			ID:              "virtual-gpt-combo",
			ExecutionPreset: "preset-multi-stage",
		},
		{
			ID:        "selector-model",
			Providers: map[string]string{"prov-1": "served-selector"},
		},
		{
			ID:        "local-model",
			Providers: map[string]string{"prov-1": "served-local"},
		},
		{
			ID:        "review-model",
			Providers: map[string]string{"prov-1": "served-review"},
		},
	}

	proj := makeTestProjection(1, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
		"token-p2": "principal-2",
		"token-p3": "principal-3",
		"token-p4": "principal-4",
		"token-p5": "principal-5",
	}, map[string]authprojection.Route{
		// P1: complete bindings with public route ids that are deliberately
		// independent from the canonical catalog ids; the selector route also
		// carries distinctive revisions so credential-binding preservation is
		// observable.
		"p1-r1": {RouteID: "pub-alpha", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "prof", UpstreamModel: "served-selector", ResourceSelector: "default", RouteRevision: 4, CredentialRevision: 9},
		"p1-r2": {RouteID: "pub-beta", PrincipalRef: "principal-1", CredentialSlotRef: "slot-2", ProfileID: "prof", UpstreamModel: "served-local", ResourceSelector: "default"},
		"p1-r3": {RouteID: "pub-gamma", PrincipalRef: "principal-1", CredentialSlotRef: "slot-3", ProfileID: "prof", UpstreamModel: "served-review", ResourceSelector: "default"},

		// P2: zero binding for the review-model reference (no served-review route).
		"p2-r1": {RouteID: "pub-alpha", PrincipalRef: "principal-2", CredentialSlotRef: "slot-1", ProfileID: "prof", UpstreamModel: "served-selector", ResourceSelector: "default"},
		"p2-r2": {RouteID: "pub-beta", PrincipalRef: "principal-2", CredentialSlotRef: "slot-2", ProfileID: "prof", UpstreamModel: "served-local", ResourceSelector: "default"},

		// P3: two distinct public routes whose catalog bindings both resolve to
		// selector-model, making that canonical reference ambiguous.
		"p3-r1":  {RouteID: "pub-alpha", PrincipalRef: "principal-3", CredentialSlotRef: "slot-1", ProfileID: "prof", UpstreamModel: "served-selector", ResourceSelector: "default"},
		"p3-r1b": {RouteID: "pub-alpha-dup", PrincipalRef: "principal-3", CredentialSlotRef: "slot-1b", ProfileID: "prof", UpstreamModel: "served-selector", ResourceSelector: "default"},
		"p3-r2":  {RouteID: "pub-beta", PrincipalRef: "principal-3", CredentialSlotRef: "slot-2", ProfileID: "prof", UpstreamModel: "served-local", ResourceSelector: "default"},
		"p3-r3":  {RouteID: "pub-gamma", PrincipalRef: "principal-3", CredentialSlotRef: "slot-3", ProfileID: "prof", UpstreamModel: "served-review", ResourceSelector: "default"},

		// P4: internal-target mismatch: served-unknown binds no catalog group, so
		// the selector-model reference has zero binding.
		"p4-r1": {RouteID: "pub-alpha", PrincipalRef: "principal-4", CredentialSlotRef: "slot-1", ProfileID: "prof", UpstreamModel: "served-unknown", ResourceSelector: "default"},
		"p4-r2": {RouteID: "pub-beta", PrincipalRef: "principal-4", CredentialSlotRef: "slot-2", ProfileID: "prof", UpstreamModel: "served-local", ResourceSelector: "default"},
		"p4-r3": {RouteID: "pub-gamma", PrincipalRef: "principal-4", CredentialSlotRef: "slot-3", ProfileID: "prof", UpstreamModel: "served-review", ResourceSelector: "default"},

		// P5: complete canonical bindings plus a projected route alias equal to the
		// virtual model id; resolution stays deterministic and the alias never
		// shadows the preset nor becomes the credential identity.
		"p5-r1": {RouteID: "pub-alpha", RouteAlias: "virtual-gpt-combo", PrincipalRef: "principal-5", CredentialSlotRef: "slot-1", ProfileID: "prof", UpstreamModel: "served-selector", ResourceSelector: "default"},
		"p5-r2": {RouteID: "pub-beta", PrincipalRef: "principal-5", CredentialSlotRef: "slot-2", ProfileID: "prof", UpstreamModel: "served-local", ResourceSelector: "default"},
		"p5-r3": {RouteID: "pub-gamma", PrincipalRef: "principal-5", CredentialSlotRef: "slot-3", ProfileID: "prof", UpstreamModel: "served-review", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj); err != nil {
		t.Fatal(err)
	}

	fakeSvc := &providerFakeRunService{poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel)}
	srv := NewServer(config.EdgeOpenAIConf{}, fakeSvc, nil)
	setManagedPrincipalProjection(srv, cache)
	srv.SetModelCatalog(catalog)
	srv.SetExecutionPresets([]config.ExecutionPreset{preset})

	// 1. P1: Authorized and listed
	reqP1 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP1.Header.Set("Authorization", "Bearer token-p1")
	wP1 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP1, reqP1)
	if wP1.Code != http.StatusOK {
		t.Fatalf("P1 /v1/models status: %d body: %s", wP1.Code, wP1.Body.String())
	}
	if !strings.Contains(wP1.Body.String(), `"id":"virtual-gpt-combo"`) {
		t.Fatalf("P1 /v1/models expected virtual-gpt-combo, got %s", wP1.Body.String())
	}

	// Verify P1 dispatch resolution
	reqP1Dispatch := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
	reqP1Dispatch.Header.Set("Authorization", "Bearer token-p1")
	principalP1, viewP1, okP1 := srv.authenticatePrincipal(reqP1Dispatch)
	if !okP1 {
		t.Fatal("P1 authentication failed")
	}
	ctxP1 := withAuthenticatedProjectionView(withPrincipal(reqP1Dispatch.Context(), principalP1), viewP1)
	dispP1, errP1 := srv.resolveRouteDispatchForPrincipal(ctxP1, "virtual-gpt-combo")
	if errP1 != nil {
		t.Fatalf("P1 resolveRouteDispatchForPrincipal failed: %v", errP1)
	}
	if !dispP1.IsPreset || dispP1.PresetID != "preset-multi-stage" || dispP1.ExternalModelID != "virtual-gpt-combo" {
		t.Fatalf("P1 unexpected dispatch: %+v", dispP1)
	}
	// Public identity is the virtual id; the credential/route identity stays the
	// selector's real projected route (pub-alpha), never the virtual id.
	if dispP1.RouteID != "pub-alpha" {
		t.Fatalf("P1 credential route id=%q, want selector projected route pub-alpha", dispP1.RouteID)
	}
	if dispP1.ModelGroupKey != "selector-model" {
		t.Fatalf("P1 canonical model group=%q, want selector-model", dispP1.ModelGroupKey)
	}
	cbP1 := dispP1.credentialBinding()
	if cbP1 == nil || cbP1.RouteID != "pub-alpha" || cbP1.CredentialSlotRef != "slot-1" || cbP1.RouteRevision != 4 || cbP1.CredentialRevision != 9 {
		t.Fatalf("P1 credential binding=%+v, want selector projected route pub-alpha rev 4/9", cbP1)
	}
	if len(dispP1.PresetResolvedBindings) != 3 {
		t.Fatalf("P1 expected 3 preset resolved bindings, got %d", len(dispP1.PresetResolvedBindings))
	}

	// 2. P2: Missing reference -> omitted from models list and dispatch fails
	reqP2 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP2.Header.Set("Authorization", "Bearer token-p2")
	wP2 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP2, reqP2)
	if strings.Contains(wP2.Body.String(), `"id":"virtual-gpt-combo"`) {
		t.Fatalf("P2 /v1/models unexpectedly included virtual-gpt-combo: %s", wP2.Body.String())
	}
	principalP2, viewP2, _ := srv.authenticatePrincipal(reqP2)
	ctxP2 := withAuthenticatedProjectionView(withPrincipal(reqP2.Context(), principalP2), viewP2)
	if _, err := srv.resolveRouteDispatchForPrincipal(ctxP2, "virtual-gpt-combo"); !errors.Is(err, ErrRouteNotFound) {
		t.Fatalf("P2 expected ErrRouteNotFound, got %v", err)
	}

	// 3. P3: two distinct public routes both bind selector-model, so that
	// canonical reference is ambiguous -> omitted from models list and dispatch fails.
	reqP3 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP3.Header.Set("Authorization", "Bearer token-p3")
	wP3 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP3, reqP3)
	if strings.Contains(wP3.Body.String(), `"id":"virtual-gpt-combo"`) {
		t.Fatalf("P3 /v1/models unexpectedly included virtual-gpt-combo: %s", wP3.Body.String())
	}
	principalP3, viewP3, _ := srv.authenticatePrincipal(reqP3)
	ctxP3 := withAuthenticatedProjectionView(withPrincipal(reqP3.Context(), principalP3), viewP3)
	if _, err := srv.resolveRouteDispatchForPrincipal(ctxP3, "virtual-gpt-combo"); !errors.Is(err, ErrRouteNotFound) {
		t.Fatalf("P3 expected ErrRouteNotFound, got %v", err)
	}

	// 4. P4: Internal-target mismatch -> omitted from models list and dispatch fails
	reqP4 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP4.Header.Set("Authorization", "Bearer token-p4")
	wP4 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP4, reqP4)
	if strings.Contains(wP4.Body.String(), `"id":"virtual-gpt-combo"`) {
		t.Fatalf("P4 /v1/models unexpectedly included virtual-gpt-combo: %s", wP4.Body.String())
	}
	principalP4, viewP4, _ := srv.authenticatePrincipal(reqP4)
	ctxP4 := withAuthenticatedProjectionView(withPrincipal(reqP4.Context(), principalP4), viewP4)
	if _, err := srv.resolveRouteDispatchForPrincipal(ctxP4, "virtual-gpt-combo"); !errors.Is(err, ErrRouteNotFound) {
		t.Fatalf("P4 expected ErrRouteNotFound, got %v", err)
	}

	// 5. P5: The virtual id collides with a projected route alias. The catalog
	// entry takes precedence for virtual-preset admission, so the collision does
	// not hide the preset or replace the selector's credential identity.
	reqP5 := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
	reqP5.Header.Set("Authorization", "Bearer token-p5")
	wP5 := httptest.NewRecorder()
	srv.routes().ServeHTTP(wP5, reqP5)
	if !strings.Contains(wP5.Body.String(), `"id":"virtual-gpt-combo"`) {
		t.Fatalf("P5 /v1/models omitted virtual-gpt-combo: %s", wP5.Body.String())
	}
	principalP5, viewP5, _ := srv.authenticatePrincipal(reqP5)
	ctxP5 := withAuthenticatedProjectionView(withPrincipal(reqP5.Context(), principalP5), viewP5)
	dispP5, errP5 := srv.resolveRouteDispatchForPrincipal(ctxP5, "virtual-gpt-combo")
	if errP5 != nil {
		t.Fatalf("P5 resolveRouteDispatchForPrincipal failed: %v", errP5)
	}
	if dispP5.ExternalModelID != "virtual-gpt-combo" || dispP5.RouteID != "pub-alpha" {
		t.Fatalf("P5 dispatch=%+v, want virtual public identity and selector route pub-alpha", dispP5)
	}
	if binding := dispP5.credentialBinding(); binding == nil || binding.RouteID != "pub-alpha" {
		t.Fatalf("P5 credential binding=%+v, want selector route pub-alpha", binding)
	}

	// 6. Revision recheck: Update projection for P1 (remove review-model)
	proj2 := makeTestProjection(2, now, time.Hour, map[string]string{
		"token-p1": "principal-1",
	}, map[string]authprojection.Route{
		"p1-r1": {RouteID: "selector-model", PrincipalRef: "principal-1", CredentialSlotRef: "slot-1", ProfileID: "prof", UpstreamModel: "served-selector", ResourceSelector: "default"},
		"p1-r2": {RouteID: "local-model", PrincipalRef: "principal-1", CredentialSlotRef: "slot-2", ProfileID: "prof", UpstreamModel: "served-local", ResourceSelector: "default"},
	})
	if err := cache.Apply(proj2); err != nil {
		t.Fatal(err)
	}
	reqP1Rev := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
	reqP1Rev.Header.Set("Authorization", "Bearer token-p1")
	principalP1Rev, viewP1Rev, _ := srv.authenticatePrincipal(reqP1Rev)
	ctxP1Rev := withAuthenticatedProjectionView(withPrincipal(reqP1Rev.Context(), principalP1Rev), viewP1Rev)
	if _, err := srv.resolveRouteDispatchForPrincipal(ctxP1Rev, "virtual-gpt-combo"); !errors.Is(err, ErrRouteNotFound) {
		t.Fatalf("P1 after revision update expected ErrRouteNotFound, got %v", err)
	}
}

func TestManagedSingleRequestPresetFailsClosed(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)

	catalog := []config.ModelCatalogEntry{
		{ID: "virtual-single-request", ExecutionPreset: "preset-sr"},
		{ID: "plan-model", Providers: map[string]string{"prov-1": "served-plan"}},
		{ID: "work-model", Providers: map[string]string{"prov-1": "served-work"}},
		{ID: "review-model", Providers: map[string]string{"prov-1": "served-review"}},
	}
	routes := map[string]authprojection.Route{
		"r-plan":   {RouteID: "pub-plan", PrincipalRef: "principal-1", CredentialSlotRef: "slot-plan", ProfileID: "prof", UpstreamModel: "served-plan", ResourceSelector: "default"},
		"r-work":   {RouteID: "pub-work", PrincipalRef: "principal-1", CredentialSlotRef: "slot-work", ProfileID: "prof", UpstreamModel: "served-work", ResourceSelector: "default"},
		"r-review": {RouteID: "pub-review", PrincipalRef: "principal-1", CredentialSlotRef: "slot-review", ProfileID: "prof", UpstreamModel: "served-review", ResourceSelector: "default"},
	}

	// markedPreset returns the approved fixed single-request preset. mutate lets a
	// caller break exactly one invariant to prove the resolver fails closed.
	markedPreset := func(mutate func(*config.ExecutionPreset)) config.ExecutionPreset {
		p := config.ExecutionPreset{
			ID:           "preset-sr",
			Selector:     config.ExecutionModelBinding{Model: "plan-model", Options: map[string]any{"reasoning_effort": "high"}},
			AllowedModes: []string{config.ModeLight},
			Routes: map[string]config.ExecutionRoute{
				config.ModeLight: {Stages: []config.ExecutionRouteStage{
					{Role: "plan", Model: "plan-model", Options: map[string]any{"reasoning_effort": "high"}},
					{Role: "work", Model: "work-model"},
					{Role: "review", Model: "review-model", Options: map[string]any{"reasoning_effort": "high"}},
				}},
			},
			SingleRequest: &config.ExecutionSingleRequestPolicy{
				WorkspaceRef: "ws-opaque-ref",
				Limits:       config.ExecutionSingleRequestLimits{WallClockMS: 30 * 60 * 1000, StageTimeoutMS: 10 * 60 * 1000, MaxToolIterations: 64, MaxOutputBytes: 16 * 1024 * 1024},
				Stages: config.ExecutionSingleRequestStages{
					Plan:   config.ExecutionSingleRequestStageConfig{Model: "plan-model", Options: map[string]any{"reasoning_effort": "high"}},
					Work:   config.ExecutionSingleRequestStageConfig{Model: "work-model"},
					Review: config.ExecutionSingleRequestStageConfig{Model: "review-model", Options: map[string]any{"reasoning_effort": "high"}},
				},
			},
		}
		if mutate != nil {
			mutate(&p)
		}
		return p
	}

	newServerFor := func(preset config.ExecutionPreset) (*Server, context.Context) {
		cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
		if err := cache.Apply(makeTestProjection(1, now, time.Hour, map[string]string{"token-p1": "principal-1"}, routes)); err != nil {
			t.Fatal(err)
		}
		srv := NewServer(config.EdgeOpenAIConf{}, &providerFakeRunService{poolDispatchPath: string(edgeservice.ProviderPoolPathTunnel)}, nil)
		setManagedPrincipalProjection(srv, cache)
		srv.SetModelCatalog(catalog)
		srv.SetExecutionPresets([]config.ExecutionPreset{preset})

		req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", nil)
		req.Header.Set("Authorization", "Bearer token-p1")
		principal, view, ok := srv.authenticatePrincipal(req)
		if !ok {
			t.Fatal("authentication failed")
		}
		return srv, withAuthenticatedProjectionView(withPrincipal(req.Context(), principal), view)
	}

	modelsBody := func(t *testing.T, srv *Server) string {
		t.Helper()
		req := httptest.NewRequest(http.MethodGet, "/v1/models", nil)
		req.Header.Set("Authorization", "Bearer token-p1")
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("/v1/models status: %d body: %s", w.Code, w.Body.String())
		}
		return w.Body.String()
	}

	t.Run("valid preset resolves and lists with frozen options", func(t *testing.T) {
		srv, ctx := newServerFor(markedPreset(nil))
		if body := modelsBody(t, srv); !strings.Contains(body, `"id":"virtual-single-request"`) {
			t.Fatalf("valid marked preset omitted from /v1/models: %s", body)
		}
		disp, err := srv.resolveRouteDispatchForPrincipal(ctx, "virtual-single-request")
		if err != nil {
			t.Fatalf("resolveRouteDispatchForPrincipal failed: %v", err)
		}
		if !disp.IsPreset || disp.PresetID != "preset-sr" || disp.ExternalModelID != "virtual-single-request" {
			t.Fatalf("unexpected dispatch: %+v", disp)
		}
		if disp.SingleRequest == nil {
			t.Fatal("expected non-nil SingleRequest admission on valid marked preset")
		}
		if disp.SingleRequest.Plan.Options["reasoning_effort"] != "high" || disp.SingleRequest.Review.Options["reasoning_effort"] != "high" {
			t.Fatalf("frozen plan/review options missing: %+v", disp.SingleRequest)
		}
		if _, present := disp.SingleRequest.Work.Options["reasoning_effort"]; present {
			t.Fatalf("work stage unexpectedly declares reasoning_effort: %+v", disp.SingleRequest.Work.Options)
		}
	})

	// Each invalid variant keeps every canonical reference authorized so the
	// rejection provably comes from the immutable compilation, not authorization.
	invalidCases := map[string]func(*config.ExecutionPreset){
		"work reasoning option": func(p *config.ExecutionPreset) {
			p.SingleRequest.Stages.Work.Options = map[string]any{"reasoning_effort": "high"}
		},
		"route policy model mismatch": func(p *config.ExecutionPreset) {
			r := p.Routes[config.ModeLight]
			r.Stages[2].Options = map[string]any{"reasoning_effort": "low"}
			p.Routes[config.ModeLight] = r
		},
		"selector options mismatch": func(p *config.ExecutionPreset) { p.Selector.Options = map[string]any{"reasoning_effort": "low"} },
		"extra route key": func(p *config.ExecutionPreset) {
			p.Routes[config.ModeDirect] = config.ExecutionRoute{}
		},
		"duplicate work role": func(p *config.ExecutionPreset) {
			r := p.Routes[config.ModeLight]
			r.Stages = []config.ExecutionRouteStage{
				{Role: "work", Model: "work-model"},
				{Role: "work", Model: "work-model"},
				{Role: "review", Model: "review-model", Options: map[string]any{"reasoning_effort": "high"}},
			}
			p.Routes[config.ModeLight] = r
		},
		"duplicate review role": func(p *config.ExecutionPreset) {
			r := p.Routes[config.ModeLight]
			r.Stages = []config.ExecutionRouteStage{
				{Role: "plan", Model: "plan-model", Options: map[string]any{"reasoning_effort": "high"}},
				{Role: "review", Model: "review-model", Options: map[string]any{"reasoning_effort": "high"}},
				{Role: "review", Model: "review-model", Options: map[string]any{"reasoning_effort": "high"}},
			}
			p.Routes[config.ModeLight] = r
		},
	}
	for name, mutate := range invalidCases {
		t.Run("invalid preset fails closed: "+name, func(t *testing.T) {
			srv, ctx := newServerFor(markedPreset(mutate))
			if body := modelsBody(t, srv); strings.Contains(body, `"id":"virtual-single-request"`) {
				t.Fatalf("invalid marked preset must be omitted from /v1/models: %s", body)
			}
			if _, err := srv.resolveRouteDispatchForPrincipal(ctx, "virtual-single-request"); !errors.Is(err, ErrRouteNotFound) {
				t.Fatalf("expected ErrRouteNotFound, got %v", err)
			}
		})
	}
}

func TestVirtualPresetModelHandlersPreservePublicIdentity(t *testing.T) {
	now := time.Date(2026, 8, 1, 12, 0, 0, 0, time.UTC)
	const (
		virtualModelID = "virtual-public-model"
		canonicalModel = "canonical-selector-model"
		projectedRoute = "projected-selector-route"
		credentialSlot = "selector-slot"
		providerID     = "provider-resource"
		servedModel    = "served-selector-model"
	)

	preset := config.ExecutionPreset{
		ID:           "preset-public-identity",
		Selector:     config.ExecutionModelBinding{Model: canonicalModel},
		AllowedModes: []string{config.ModeDirect},
		Routes:       map[string]config.ExecutionRoute{config.ModeDirect: {}},
	}

	newServer := func(route authprojection.Route, candidate edgeservice.ProviderPoolCandidate, frames chan *iop.ProviderTunnelFrame) (*Server, *providerFakeRunService) {
		t.Helper()
		cache := authprojection.NewCache(authprojection.DefaultLimits(), func() time.Time { return now })
		projection := makeTestProjection(1, now, time.Hour, map[string]string{"managed-token": "principal-1"}, map[string]authprojection.Route{"selector": route})
		if err := cache.Apply(projection); err != nil {
			t.Fatal(err)
		}
		fake := &providerFakeRunService{
			poolDispatchPath:      string(edgeservice.ProviderPoolPathTunnel),
			poolSelectedCandidate: candidate,
			tunnelFrames:          frames,
		}
		srv := NewServer(config.EdgeOpenAIConf{}, fake, nil)
		srv.SetEdgeID("edge-principal-public-identity")
		setManagedPrincipalProjection(srv, cache)
		srv.SetExecutionPresets([]config.ExecutionPreset{preset})
		srv.SetModelCatalog([]config.ModelCatalogEntry{
			{ID: virtualModelID, ExecutionPreset: preset.ID},
			{ID: canonicalModel, Providers: map[string]string{providerID: servedModel}},
		})
		return srv, fake
	}

	assertSelectorBinding := func(t *testing.T, fake *providerFakeRunService) {
		t.Helper()
		runs := fake.tunnelReqsSnapshot()
		if len(runs) != 1 {
			t.Fatalf("tunnel requests=%d, want 1", len(runs))
		}
		binding := runs[0].CredentialBinding
		if binding == nil || binding.RouteID != projectedRoute || binding.CredentialSlotRef != credentialSlot {
			t.Fatalf("credential binding=%+v, want projected selector route %q", binding, projectedRoute)
		}
		if run := fake.poolLastRunSnapshot(); run.ModelGroupKey != canonicalModel {
			t.Fatalf("model group=%q, want canonical selector %q", run.ModelGroupKey, canonicalModel)
		}
	}

	t.Run("chat completions", func(t *testing.T) {
		route := authprojection.Route{
			RouteID: projectedRoute, PrincipalRef: "principal-1", CredentialSlotRef: credentialSlot,
			ProfileID: "chat-profile", UpstreamModel: servedModel, ResourceSelector: providerID,
		}
		candidate := anthropicTestCandidate(t, "openai")
		candidate.ProviderID = providerID
		candidate.ProfileID = route.ProfileID
		candidate.ActualModel = servedModel
		srv, fake := newServer(route, candidate, staticProviderTunnelFrames(`{"id":"chatcmpl-public","object":"chat.completion","model":"served-selector-model","choices":[{"message":{"role":"assistant","content":"ok"},"finish_reason":"stop"}]}`))
		req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{"model":"virtual-public-model","messages":[{"role":"user","content":"hi"}]}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		var response chatCompletionResponse
		if err := json.Unmarshal(w.Body.Bytes(), &response); err != nil {
			t.Fatal(err)
		}
		if response.ID != "chatcmpl-public" {
			t.Fatalf("response id=%q, want exact provider ID %q", response.ID, "chatcmpl-public")
		}
		if response.Model != virtualModelID {
			t.Fatalf("response model=%q, want public virtual model %q", response.Model, virtualModelID)
		}
		assertSelectorBinding(t, fake)
		assertHotPathTerminal(t, srv)
	})

	t.Run("anthropic messages bridge", func(t *testing.T) {
		candidate := anthropicTestCandidate(t, "openai")
		candidate.ProviderID = providerID
		candidate.ActualModel = servedModel
		route := authprojection.Route{
			RouteID: projectedRoute, PrincipalRef: "principal-1", CredentialSlotRef: credentialSlot,
			ProfileID: candidate.ProfileID, UpstreamModel: servedModel, ResourceSelector: providerID,
		}
		srv, fake := newServer(route, candidate, anthropicTunnelFrames(http.StatusOK, "application/json", []byte(`{"id":"chatcmpl-public","object":"chat.completion","model":"served-selector-model","choices":[{"message":{"role":"assistant","content":"ok"},"finish_reason":"stop"}]}`)))
		req := httptest.NewRequest(http.MethodPost, "/v1/messages", strings.NewReader(`{"model":"virtual-public-model","max_tokens":8,"messages":[{"role":"user","content":"hi"}]}`))
		req.Header.Set("Authorization", "Bearer managed-token")
		req.Header.Set(anthropicVersionHeader, anthropicSupportedVersion)
		w := httptest.NewRecorder()
		srv.routes().ServeHTTP(w, req)
		if w.Code != http.StatusOK {
			t.Fatalf("status=%d body=%s", w.Code, w.Body.String())
		}
		var response anthropicMessageResponse
		if err := json.Unmarshal(w.Body.Bytes(), &response); err != nil {
			t.Fatal(err)
		}
		if response.ID != "chatcmpl-public" {
			t.Fatalf("response id=%q, want exact provider ID %q", response.ID, "chatcmpl-public")
		}
		if response.Model != virtualModelID {
			t.Fatalf("response model=%q, want public virtual model %q", response.Model, virtualModelID)
		}
		assertSelectorBinding(t, fake)
		assertHotPathTerminal(t, srv)
	})
}
