package main

import (
	"reflect"
	"testing"
)

// providerMapEntryCase describes one provider map entry verification case.
type providerMapEntryCase struct {
	name      string
	entries   map[string]interface{}
	selector  string
	wantPath  string
	wantValue interface{}
}

// providerMapEntryCases is the table of provider map entry verification cases.
var providerMapEntryCases = []providerMapEntryCase{
	{
		name:      "scalar value matches selector",
		entries:   map[string]interface{}{"scalar-provider": "gx10-vllm"},
		selector:  "gx10-vllm",
		wantPath:  "model.active_edge_model_group.providers.scalar-provider",
		wantValue: "gx10-vllm",
	},
	{
		name: "entity id matches selector",
		entries: map[string]interface{}{
			"some-other-key": map[string]interface{}{
				"id":     "gx10-vllm",
				"type":   "vllm",
				"region": "us",
			},
		},
		selector:  "gx10-vllm",
		wantPath:  "model.active_edge_model_group.providers.some-other-key",
		wantValue: map[string]interface{}{"id": "gx10-vllm", "type": "vllm", "region": "us"},
	},
	{
		name: "entity provider field matches selector",
		entries: map[string]interface{}{
			"another-key": map[string]interface{}{
				"provider": "gx10-vllm",
				"type":     "vllm",
			},
		},
		selector:  "gx10-vllm",
		wantPath:  "model.active_edge_model_group.providers.another-key",
		wantValue: map[string]interface{}{"provider": "gx10-vllm", "type": "vllm"},
	},
	{
		name:      "key and value both match selector dedupes",
		entries:   map[string]interface{}{"gx10-vllm": "gx10-vllm"},
		selector:  "gx10-vllm",
		wantPath:  "model.active_edge_model_group.providers.gx10-vllm",
		wantValue: "gx10-vllm",
	},
}

// TestQueryProviderMatchesMapEntries verifies each provider map entry shape
// with an independent fixture so scalar, entity id, entity provider, and
// key+value dedupe cases run in isolation.
func TestQueryProviderMatchesMapEntries(t *testing.T) {
	for _, tc := range providerMapEntryCases {
		tc := tc
		t.Run(tc.name, func(t *testing.T) {
			verifyProviderMapEntry(t, tc)
		})
	}
}

// verifyProviderMapEntry runs the query and asserts path/value/dedupe for one case.
func verifyProviderMapEntry(t *testing.T, tc providerMapEntryCase) {
	t.Helper()
	data := parseFixture(t)
	setProviderEntries(t, data, tc.entries)
	matches := queryProviders(data, tc.selector)
	assertProviderEntryMatch(t, matches, tc)
}

// assertProviderEntryMatch checks that matches contains the expected path
// with the exact value, no duplicate paths, and paths sorted ascending.
func assertProviderEntryMatch(t *testing.T, matches []match, tc providerMapEntryCase) {
	t.Helper()
	if len(matches) == 0 {
		t.Fatalf("expected at least 1 match for %q, got 0", tc.selector)
	}
	found := false
	for _, m := range matches {
		if m.Path == tc.wantPath {
			found = true
			if !reflect.DeepEqual(m.Value, tc.wantValue) {
				t.Errorf("value at %s = %#v, want %#v", tc.wantPath, m.Value, tc.wantValue)
			}
			break
		}
	}
	if !found {
		t.Errorf("expected match at %s for %q, got %+v", tc.wantPath, tc.selector, matches)
	}
	assertMatchPathsSorted(t, matches)
	pathCount := make(map[string]int)
	for _, m := range matches {
		pathCount[m.Path]++
	}
	for p, count := range pathCount {
		if count > 1 {
			t.Errorf("duplicate path %s: %d", p, count)
		}
	}
}

// assertMatchPathsSorted verifies that match paths are in ascending order.
func assertMatchPathsSorted(t *testing.T, matches []match) {
	t.Helper()
	for i := 1; i < len(matches); i++ {
		if matches[i].Path < matches[i-1].Path {
			t.Errorf("matches not sorted: %s < %s", matches[i].Path, matches[i-1].Path)
		}
	}
}

// setProviderEntries replaces active_edge_model_group.providers with the given entries.
func setProviderEntries(t *testing.T, data map[string]interface{}, entries map[string]interface{}) {
	t.Helper()
	model, ok := data["model"].(map[string]interface{})
	if !ok {
		t.Fatalf("model not a map")
	}
	activeGroup, ok := model["active_edge_model_group"].(map[string]interface{})
	if !ok {
		t.Fatalf("active_edge_model_group not a map")
	}
	activeGroup["providers"] = entries
}
