package store

import (
	"strings"
	"testing"
)

func TestMaskAdminGatewayTaskRecursivelyMasksSecretsWithoutMutatingSource(t *testing.T) {
	source := AdminGatewayTask{
		GatewayTask: GatewayTask{
			ErrorCode:    "http_404",
			ErrorMessage: "404 page not found from upstream route /private/v1/images",
			Request: map[string]any{
				"model": "example",
				"headers": map[string]any{
					"Authorization": "Bearer private",
					"X-Api-Key":     "secret-key",
				},
				"usage": map[string]any{"input_tokens": float64(12)},
			},
			Result: map[string]any{
				"nested": []any{map[string]any{"password": "private-password"}},
			},
			Attempts: []TaskAttempt{{
				ErrorCode:       "http_404",
				ErrorMessage:    "404 page not found from upstream route /private/v1/images",
				RequestSnapshot: map[string]any{"client_secret": "private-client-secret"},
			}},
		},
	}

	masked := MaskAdminGatewayTask(source)
	if masked.ErrorCode != source.ErrorCode || masked.ErrorMessage != source.ErrorMessage || masked.Attempts[0].ErrorMessage != source.Attempts[0].ErrorMessage {
		t.Fatalf("admin error audit fields must preserve raw upstream values: %#v", masked)
	}
	headers := masked.Request["headers"].(map[string]any)
	if headers["Authorization"] != maskedAdminTaskValue || headers["X-Api-Key"] != maskedAdminTaskValue {
		t.Fatalf("sensitive headers were not masked: %#v", headers)
	}
	if masked.Request["usage"].(map[string]any)["input_tokens"] != float64(12) {
		t.Fatalf("token usage must remain visible: %#v", masked.Request)
	}
	nested := masked.Result["nested"].([]any)[0].(map[string]any)
	if nested["password"] != maskedAdminTaskValue {
		t.Fatalf("nested password was not masked: %#v", nested)
	}
	if masked.Attempts[0].RequestSnapshot["client_secret"] != maskedAdminTaskValue {
		t.Fatalf("attempt snapshot secret was not masked: %#v", masked.Attempts[0])
	}
	if source.Request["headers"].(map[string]any)["Authorization"] != "Bearer private" {
		t.Fatal("masking mutated the source request")
	}
	if source.Attempts[0].RequestSnapshot["client_secret"] != "private-client-secret" {
		t.Fatal("masking mutated the source attempts")
	}
}

func TestBuildAdminTaskWhereUsesSharedPlaceholdersAndAllFilters(t *testing.T) {
	where, args := buildAdminTaskWhere(AdminTaskListFilter{
		Query:         "needle",
		GatewayTenant: "00000000-0000-0000-0000-000000000001",
		GatewayUser:   "00000000-0000-0000-0000-000000000002",
		UserGroup:     "00000000-0000-0000-0000-000000000003",
		Status:        "failed",
		Platform:      "00000000-0000-0000-0000-000000000004",
		Model:         "model-a",
		ModelType:     "image_generate",
		RunMode:       "production",
		BillingStatus: "settled",
		APIKey:        "ops",
	})
	sql := strings.Join(where, "\n")
	if strings.Contains(sql, "%!") || strings.Contains(sql, "$%d") {
		t.Fatalf("SQL contains an unresolved placeholder: %s", sql)
	}
	if len(args) != 11 {
		t.Fatalf("argument count=%d, want 11", len(args))
	}
	if strings.Count(sql, "$1") < 10 {
		t.Fatalf("keyword search should reuse one placeholder, got: %s", sql)
	}
	for _, fragment := range []string{
		"t.gateway_tenant_id",
		"t.gateway_user_id",
		"t.user_group_id",
		"platform_attempt.platform_id",
		"t.billing_status",
		"t.api_key_prefix",
	} {
		if !strings.Contains(sql, fragment) {
			t.Fatalf("SQL is missing %q: %s", fragment, sql)
		}
	}
}
