package backend

import (
	"strings"
	"testing"
)

func TestComposeVideoExtractPromptDefaultBaseAndAttributes(t *testing.T) {
	got := ComposeVideoExtractPrompt("")
	for _, want := range []string{
		`"caption_zh"`,
		`"attributes"`,
		"at most 30",
		"at most 64 characters",
		"at most 255 characters",
		`must not start with "drive9."`,
	} {
		if !strings.Contains(got, want) {
			t.Fatalf("effective video prompt missing %q: %q", want, got)
		}
	}
	if count := strings.Count(got, `"attributes"`); count != 1 {
		t.Fatalf("video attributes contract declared %d times, want 1", count)
	}
}

func TestComposeVideoExtractPromptPreservesTenantBaseAndAttributes(t *testing.T) {
	got := ComposeVideoExtractPrompt("  focus on presentation slides  ")
	if !strings.HasPrefix(got, "focus on presentation slides") {
		t.Fatalf("effective video prompt lost tenant base: %q", got)
	}
	if !strings.HasSuffix(got, videoAttributesSuffix) {
		t.Fatalf("effective video prompt missing fixed attributes suffix: %q", got)
	}
}

func TestOpenAIVideoExtractorStoresOneEffectivePromptForEveryStage(t *testing.T) {
	extractor, err := NewOpenAIVideoTextExtractor(OpenAIVideoTextExtractorConfig{
		BaseURL: "https://extractor.example.com",
		APIKey:  "secret",
		Model:   "vision-model",
		Prompt:  "focus on presentation slides",
	})
	if err != nil {
		t.Fatal(err)
	}
	want := ComposeVideoExtractPrompt("focus on presentation slides")
	if extractor.prompt != want {
		t.Fatalf("extractor prompt=%q, want %q", extractor.prompt, want)
	}
	if count := strings.Count(extractor.prompt, `"attributes"`); count != 1 {
		t.Fatalf("extractor attributes contract declared %d times, want 1", count)
	}
}

func TestComposeAudioExtractPromptDefaultContract(t *testing.T) {
	got := ComposeAudioExtractPrompt("")
	for _, want := range []string{
		"Transcribe the audio faithfully",
		`"transcript"`,
		`"attributes"`,
		`"language"`,
		`"topic"`,
		`"speaker_count"`,
		"at most 30",
		"at most 64 characters",
		"at most 255 characters",
		`must not start with "drive9."`,
	} {
		if !strings.Contains(got, want) {
			t.Fatalf("effective audio prompt missing %q: %q", want, got)
		}
	}
	if strings.Contains(got, audioTenantContextHeading) {
		t.Fatalf("empty tenant prompt added tenant context section: %q", got)
	}
}

func TestComposeAudioExtractPromptTreatsTenantPromptAsContext(t *testing.T) {
	const tenantPrompt = "Product names: TiDB, Drive9. Prefer Singapore English."
	got := ComposeAudioExtractPrompt("  " + tenantPrompt + "  ")
	defaultAt := strings.Index(got, defaultAudioExtractPrompt)
	tenantAt := strings.Index(got, audioTenantContextHeading)
	suffixAt := strings.Index(got, audioOutputSuffix)
	if defaultAt != 0 || tenantAt <= defaultAt || suffixAt <= tenantAt {
		t.Fatalf("audio prompt order is not default, tenant context, suffix: %q", got)
	}
	if strings.Count(got, tenantPrompt) != 1 {
		t.Fatalf("tenant context not preserved exactly once: %q", got)
	}
}
