package modelaccess

import (
	"reflect"
	"testing"
)

func TestScopeAllowsTaskPreservesAliases(t *testing.T) {
	tests := []struct {
		scopes  []string
		kind    string
		allowed bool
	}{
		{[]string{"chat"}, "responses", true},
		{[]string{"text_generate"}, "chat.completions", true},
		{[]string{"image"}, "images.vectorize", true},
		{[]string{"video"}, "videos.upscales", true},
		{[]string{"audio_generate"}, "music.generations", true},
		{[]string{"text_to_speech"}, "speech.generations", true},
		{[]string{"image"}, "chat.completions", false},
		{nil, "chat.completions", true},
	}
	for _, test := range tests {
		if got := ScopeAllowsTask(test.scopes, test.kind); got != test.allowed {
			t.Fatalf("ScopeAllowsTask(%v, %q) = %v, want %v", test.scopes, test.kind, got, test.allowed)
		}
	}
}

func TestFilterModelTypesUsesCapabilityScopes(t *testing.T) {
	tests := []struct {
		name   string
		scopes []string
		types  []string
		want   []string
	}{
		{"image", []string{"image"}, []string{"text_generate", "image_generate", "image_edit"}, []string{"image_generate", "image_edit"}},
		{"video alias", []string{"video"}, []string{"image_to_video", "video_enhance", "text_generate"}, []string{"image_to_video", "video_enhance"}},
		{"custom exact", []string{"custom_type"}, []string{"custom_type", "other_type"}, []string{"custom_type"}},
		{"all", []string{"all"}, []string{"text_generate", "unknown"}, []string{"text_generate", "unknown"}},
		{"legacy empty", nil, []string{"text_generate", "unknown"}, []string{"text_generate", "unknown"}},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			if got := FilterModelTypes(test.scopes, test.types); !reflect.DeepEqual(got, test.want) {
				t.Fatalf("FilterModelTypes(%v, %v) = %v, want %v", test.scopes, test.types, got, test.want)
			}
		})
	}
}

func TestKnownTaskKindsUseExpectedScopes(t *testing.T) {
	tests := []struct {
		kind  string
		scope string
	}{
		{"chat.completions", "chat"},
		{"responses", "text_generate"},
		{"embeddings", "text_embedding"},
		{"reranks", "text_rerank"},
		{"images.generations", "image"},
		{"images.edits", "image"},
		{"images.vectorize", "vectorize"},
		{"videos.generations", "video"},
		{"videos.upscales", "video_upscale"},
		{"song.generations", "song"},
		{"music.generations", "music_generate"},
		{"speech.generations", "tts"},
		{"voice.clone", "audio"},
	}
	for _, test := range tests {
		t.Run(test.kind, func(t *testing.T) {
			if !ScopeAllowsTask([]string{test.scope}, test.kind) {
				t.Fatalf("scope %q should allow task %q", test.scope, test.kind)
			}
			if ScopeAllowsTask([]string{"unrelated"}, test.kind) {
				t.Fatalf("unrelated scope allowed task %q", test.kind)
			}
		})
	}
}

func TestKnownModelTypesUseExpectedScopes(t *testing.T) {
	tests := []struct {
		modelType string
		scope     string
	}{
		{"text_generate", "chat"},
		{"tools_call", "text"},
		{"text_embedding", "embedding"},
		{"text_rerank", "rerank"},
		{"image_generate", "image"},
		{"image_edit", "image"},
		{"image_analysis", "image"},
		{"image_vectorize", "vectorize"},
		{"video_generate", "video"},
		{"image_to_video", "video"},
		{"text_to_video", "video"},
		{"video_edit", "video"},
		{"video_reference", "video"},
		{"video_first_last_frame", "video"},
		{"video_understanding", "video"},
		{"omni_video", "video"},
		{"omni", "video"},
		{"video_enhance", "upscale"},
		{"audio_generate", "music"},
		{"music_generate", "song"},
		{"text_to_speech", "speech"},
		{"audio_understanding", "audio"},
		{"voice_clone", "tts"},
	}
	for _, test := range tests {
		t.Run(test.modelType, func(t *testing.T) {
			if !ScopeAllowsModelType([]string{test.scope}, test.modelType) {
				t.Fatalf("scope %q should allow model type %q", test.scope, test.modelType)
			}
			if ScopeAllowsModelType([]string{"unrelated"}, test.modelType) {
				t.Fatalf("unrelated scope allowed model type %q", test.modelType)
			}
		})
	}
}
