package repository

import (
	"encoding/json"
	"os"
	"path/filepath"
	"testing"
)

// Keep the migration contract executable without connecting to a Mongo instance.
// The legacy owner+external identity must remain the only Opportunity identity;
// ProductMatch indexes are query helpers, never a replacement for that key.
func TestProductRadarIndexesPreserveOpportunityIdentity(t *testing.T) {
	var groups []struct {
		CreateIndexes string `json:"createIndexes"`
		Indexes       []struct {
			Key    map[string]int `json:"key"`
			Name   string         `json:"name"`
			Unique bool           `json:"unique"`
		} `json:"indexes"`
	}
	base := filepath.Join("..", "..", "..", "..", "generate", "database", "mongo")
	read := func(name string) {
		b, err := os.ReadFile(filepath.Join(base, name))
		if err != nil {
			t.Fatal(err)
		}
		var next []struct {
			CreateIndexes string `json:"createIndexes"`
			Indexes       []struct {
				Key    map[string]int `json:"key"`
				Name   string         `json:"name"`
				Unique bool           `json:"unique"`
			} `json:"indexes"`
		}
		if err := json.Unmarshal(b, &next); err != nil {
			t.Fatal(err)
		}
		groups = append(groups, next...)
	}
	read("000014_demand_radar_indexes.up.json")
	read("000015_brand_product_radar_indexes.up.json")
	var foundProductMatch, foundLegacyUnique bool
	for _, group := range groups {
		for _, index := range group.Indexes {
			if group.CreateIndexes == "radar_opportunities" && index.Unique {
				if len(index.Key) != 2 || index.Key["owner_uid"] != 1 || index.Key["external_id"] != 1 {
					t.Fatalf("legacy Opportunity unique key changed: %#v", index.Key)
				}
				if _, hasProduct := index.Key["product_id"]; hasProduct {
					t.Fatal("legacy Opportunity unique key must not include product_id")
				}
				foundLegacyUnique = true
			}
			if index.Name == "owner_opportunities_product_match" {
				foundProductMatch = true
			}
		}
	}
	if !foundLegacyUnique {
		t.Fatal("legacy Opportunity unique index not represented")
	}
	if !foundProductMatch {
		t.Fatal("ProductMatch query index not represented")
	}
}

func TestOpportunityInboxReviewIndexes(t *testing.T) {
	path := filepath.Join("..", "..", "..", "..", "generate", "database", "mongo", "000016_opportunity_inbox_review_indexes.up.json")
	b, err := os.ReadFile(path)
	if err != nil {
		t.Fatal(err)
	}
	var groups []struct {
		CreateIndexes string `json:"createIndexes"`
		Indexes       []struct {
			Name string `json:"name"`
		} `json:"indexes"`
	}
	if err := json.Unmarshal(b, &groups); err != nil {
		t.Fatal(err)
	}
	foundReview := map[string]bool{}
	for _, group := range groups {
		for _, index := range group.Indexes {
			foundReview[index.Name] = group.CreateIndexes == "radar_opportunities" || group.CreateIndexes == "radar_opportunity_review_events"
		}
	}
	for _, name := range []string{"owner_opportunities_review_posted", "owner_opportunities_tombstone", "owner_opportunity_review_events"} {
		if !foundReview[name] {
			t.Fatalf("missing review index %s", name)
		}
	}
}
