package sqlite

import (
	"context"
	"testing"
)

func TestRouteDecisionLogsRepoCreateAndListRecent(t *testing.T) {
	t.Parallel()

	store := openTestDB(t)
	ctx := context.Background()

	if _, err := store.RouteDecisionLogs().Create(ctx, RouteDecisionLog{
		RequestID:             "req-1",
		LogicalGroupID:        "gpt-shared",
		PublicModel:           "gpt-5.4",
		UserKey:               "user-a",
		ConversationKey:       "conv-a",
		StickyKey:             "sticky-a",
		StickyKeyType:         "conversation",
		StickyHit:             true,
		SelectedRouteID:       "asxs",
		SelectedShadowGroupID: "gpt-shared__asxs",
		FallbackUsed:          false,
		ErrorClass:            "",
		UpstreamStatus:        200,
		LatencyMS:             123,
	}); err != nil {
		t.Fatalf("RouteDecisionLogs().Create() error = %v", err)
	}

	logs, err := store.RouteDecisionLogs().ListRecent(ctx, RouteDecisionLogFilter{
		LogicalGroupID: "gpt-shared",
		Limit:          10,
	})
	if err != nil {
		t.Fatalf("RouteDecisionLogs().ListRecent() error = %v", err)
	}
	if len(logs) != 1 {
		t.Fatalf("RouteDecisionLogs().ListRecent() len = %d, want 1", len(logs))
	}
	if logs[0].SelectedRouteID != "asxs" || !logs[0].StickyHit || logs[0].UpstreamStatus != 200 {
		t.Fatalf("RouteDecisionLogs().ListRecent()[0] = %+v", logs[0])
	}
}

func TestRouteFailoverEventsRepoCreateAndListRecent(t *testing.T) {
	t.Parallel()

	store := openTestDB(t)
	ctx := context.Background()

	if _, err := store.RouteFailoverEvents().Create(ctx, RouteFailoverEvent{
		RequestID:      "req-2",
		LogicalGroupID: "gpt-shared",
		PublicModel:    "gpt-5.4",
		FromRouteID:    "asxs",
		ToRouteID:      "codex2api",
		Reason:         "upstream_5xx",
		FailureCount:   2,
	}); err != nil {
		t.Fatalf("RouteFailoverEvents().Create() error = %v", err)
	}

	items, err := store.RouteFailoverEvents().ListRecent(ctx, RouteFailoverEventFilter{
		RequestID: "req-2",
		Limit:     10,
	})
	if err != nil {
		t.Fatalf("RouteFailoverEvents().ListRecent() error = %v", err)
	}
	if len(items) != 1 {
		t.Fatalf("RouteFailoverEvents().ListRecent() len = %d, want 1", len(items))
	}
	if items[0].ToRouteID != "codex2api" || items[0].FailureCount != 2 {
		t.Fatalf("RouteFailoverEvents().ListRecent()[0] = %+v", items[0])
	}
}

func TestRouteStickyAuditRepoCreateAndListRecent(t *testing.T) {
	t.Parallel()

	store := openTestDB(t)
	ctx := context.Background()

	if _, err := store.RouteStickyAudit().Create(ctx, RouteStickyAudit{
		StickyKey:      "sticky-3",
		StickyKeyType:  "user_model",
		LogicalGroupID: "gpt-shared",
		PublicModel:    "gpt-5.4-mini",
		RouteID:        "asxs",
		Action:         "bind",
		ExpiresAt:      "2026-05-28T18:00:00Z",
	}); err != nil {
		t.Fatalf("RouteStickyAudit().Create() error = %v", err)
	}

	items, err := store.RouteStickyAudit().ListRecent(ctx, RouteStickyAuditFilter{
		StickyKey: "sticky-3",
		Limit:     10,
	})
	if err != nil {
		t.Fatalf("RouteStickyAudit().ListRecent() error = %v", err)
	}
	if len(items) != 1 {
		t.Fatalf("RouteStickyAudit().ListRecent() len = %d, want 1", len(items))
	}
	if items[0].Action != "bind" || items[0].RouteID != "asxs" {
		t.Fatalf("RouteStickyAudit().ListRecent()[0] = %+v", items[0])
	}
}

func TestRouteLoggingReposRejectInvalidRows(t *testing.T) {
	t.Parallel()

	store := openTestDB(t)
	ctx := context.Background()

	if _, err := store.RouteDecisionLogs().Create(ctx, RouteDecisionLog{}); err == nil {
		t.Fatal("RouteDecisionLogs().Create() error = nil, want validation error")
	}
	if _, err := store.RouteFailoverEvents().Create(ctx, RouteFailoverEvent{}); err == nil {
		t.Fatal("RouteFailoverEvents().Create() error = nil, want validation error")
	}
	if _, err := store.RouteStickyAudit().Create(ctx, RouteStickyAudit{}); err == nil {
		t.Fatal("RouteStickyAudit().Create() error = nil, want validation error")
	}
}
