package main

import (
	"testing"
	"time"

	"github.com/mem9-ai/drive9/pkg/backend"
)

var imageExtractEnvKeys = []string{
	"DRIVE9_IMAGE_EXTRACT_ENABLED",
	"DRIVE9_IMAGE_EXTRACT_API_BASE",
	"DRIVE9_IMAGE_EXTRACT_API_KEY",
	"DRIVE9_IMAGE_EXTRACT_MODEL",
	"DRIVE9_IMAGE_EXTRACT_PROMPT",
	"DRIVE9_IMAGE_EXTRACT_GLOBAL_DISABLED",
}

func unsetImageExtractEnv(t *testing.T) {
	t.Helper()
	restore := snapshotEnv(t, imageExtractEnvKeys)
	t.Cleanup(func() { restoreEnv(t, restore) })
	unsetEnv(t, imageExtractEnvKeys)
}

// Step-1 acceptance: the resolver-backed capability is set even when
// DRIVE9_IMAGE_EXTRACT_ENABLED=false — the process-default extractor stays
// off, but per-tenant configs resolved at execution time can still run
// img_extract_text.
func TestWithExtractResolverCapabilitiesSetsCapabilitiesWithoutDefaultExtractors(t *testing.T) {
	opts := withExtractResolverCapabilities(backend.Options{})
	if !opts.AsyncImageExtract.Capability {
		t.Fatal("image capability not set")
	}
	if !opts.AsyncAudioExtract.Capability || !opts.AsyncVideoExtract.Capability {
		t.Fatalf("media capabilities = audio:%v video:%v, want true", opts.AsyncAudioExtract.Capability, opts.AsyncVideoExtract.Capability)
	}
	if opts.AsyncImageExtract.Enabled || opts.AsyncImageExtract.Extractor != nil {
		t.Fatal("capability must not enable the process-default extractor")
	}
	if !backend.AsyncImageExtractWillWireRuntime(opts.AsyncImageExtract) {
		t.Fatal("capability-only options must still wire the runtime")
	}
	if backend.AsyncImageExtractWillWireRuntime(backend.AsyncImageExtractOptions{}) {
		t.Fatal("zero options must not wire the runtime")
	}
}

func TestImageExtractGlobalDisabledFromEnv(t *testing.T) {
	unsetImageExtractEnv(t)
	if imageExtractGlobalDisabledFromEnv() {
		t.Fatal("kill switch must default to false")
	}
	for _, raw := range []string{"1", "true", "TRUE", "yes", "on"} {
		t.Setenv("DRIVE9_IMAGE_EXTRACT_GLOBAL_DISABLED", raw)
		if !imageExtractGlobalDisabledFromEnv() {
			t.Fatalf("DRIVE9_IMAGE_EXTRACT_GLOBAL_DISABLED=%q must enable the kill switch", raw)
		}
	}
	for _, raw := range []string{"0", "false", "no", "off", "bogus"} {
		t.Setenv("DRIVE9_IMAGE_EXTRACT_GLOBAL_DISABLED", raw)
		if imageExtractGlobalDisabledFromEnv() {
			t.Fatalf("DRIVE9_IMAGE_EXTRACT_GLOBAL_DISABLED=%q must not enable the kill switch", raw)
		}
	}
}

func TestDefaultImageExtractRuntime(t *testing.T) {
	if got := defaultImageExtractRuntime(backend.AsyncImageExtractOptions{}); got != nil {
		t.Fatalf("disabled options yielded runtime %+v, want nil", got)
	}
	if got := defaultImageExtractRuntime(backend.AsyncImageExtractOptions{Enabled: true}); got != nil {
		t.Fatalf("enabled options without extractor yielded runtime %+v, want nil", got)
	}
	extractor := backend.NewBasicImageTextExtractor()
	async := backend.AsyncImageExtractOptions{
		Enabled:             true,
		Extractor:           extractor,
		TaskTimeout:         11 * time.Second,
		MaxSourceBytes:      16384,
		MaxImageBytes:       4096,
		MaxExtractTextBytes: 8192,
	}
	rt := defaultImageExtractRuntime(async)
	if rt == nil {
		t.Fatal("expected a runtime for enabled options")
	}
	if rt.Timeout != 11*time.Second || rt.MaxSourceBytes != 16384 || rt.MaxImageBytes != 4096 || rt.MaxExtractTextBytes != 8192 {
		t.Fatalf("runtime limits = %+v, want mapped from async options", rt)
	}
}

func TestBuildBackendOptionsReturnsImageExtractDefaultProvider(t *testing.T) {
	unsetImageExtractEnv(t)
	_, got, err := buildBackendOptionsFromEnv()
	if err != nil {
		t.Fatalf("buildBackendOptionsFromEnv: %v", err)
	}
	if got != nil {
		t.Fatalf("disabled image extract yielded provider %+v, want nil", got)
	}

	t.Setenv("DRIVE9_IMAGE_EXTRACT_ENABLED", "true")
	_, got, err = buildBackendOptionsFromEnv()
	if err != nil {
		t.Fatalf("buildBackendOptionsFromEnv: %v", err)
	}
	if got != nil {
		t.Fatalf("basic-only default yielded provider %+v, want nil", got)
	}

	t.Setenv("DRIVE9_IMAGE_EXTRACT_API_BASE", "https://api.example.com")
	t.Setenv("DRIVE9_IMAGE_EXTRACT_API_KEY", "sk-test")
	t.Setenv("DRIVE9_IMAGE_EXTRACT_MODEL", "vision-1")
	t.Setenv("DRIVE9_IMAGE_EXTRACT_PROMPT", "  describe it  ")
	_, got, err = buildBackendOptionsFromEnv()
	if err != nil {
		t.Fatalf("buildBackendOptionsFromEnv: %v", err)
	}
	if got == nil {
		t.Fatal("full provider env yielded nil provider")
	}
	if got.APIBase != "https://api.example.com" || got.APIKey != "sk-test" || got.Model != "vision-1" {
		t.Fatalf("provider = %+v", got)
	}
	if got.Prompt != "describe it" {
		t.Fatalf("prompt = %q, want trimmed raw prompt", got.Prompt)
	}
}

func TestConfigureExtractResolverRequiresStoreAndPool(t *testing.T) {
	wired, err := configureExtractResolver(nil, nil, nil, backend.Options{}, nil)
	if err != nil {
		t.Fatal(err)
	}
	if wired {
		t.Fatal("resolver must not be wired without store and pool")
	}
}
