package schemacatalog

import (
	"reflect"
	"testing"
)

func TestHistoryTrackingTemporalCatalogContract(t *testing.T) {
	defs, err := SystemTableDefinitions()
	if err != nil {
		t.Fatalf("SystemTableDefinitions(): %v", err)
	}
	byName := make(map[string]struct {
		columns     map[string]string
		indices     map[string][]string
		indexUnique map[string]bool
		foreignKeys int
	}, len(defs))
	for _, def := range defs {
		entry := struct {
			columns     map[string]string
			indices     map[string][]string
			indexUnique map[string]bool
			foreignKeys int
		}{columns: map[string]string{}, indices: map[string][]string{}, indexUnique: map[string]bool{}, foreignKeys: len(def.ForeignKeys)}
		for _, column := range def.Columns {
			entry.columns[column.Name] = column.Type
		}
		for _, index := range def.Indices {
			entry.indices[index.Name] = index.Columns
			entry.indexUnique[index.Name] = index.Unique
		}
		byName[def.TableName] = entry
	}
	if got := byName["_System_Field"].columns["HistoryTrackingRevision"]; got != "BIGINT" {
		t.Fatalf("_System_Field.HistoryTrackingRevision type = %q, want BIGINT", got)
	}
	if got := byName["_System_AuditLog"].columns["EventAt"]; got != "DATETIME(6)" {
		t.Fatalf("_System_AuditLog.EventAt type = %q, want DATETIME(6)", got)
	}
	if got := byName["_System_AuditLog"].columns["HistorySequence"]; got != "BIGINT" {
		t.Fatalf("_System_AuditLog.HistorySequence type = %q, want BIGINT", got)
	}
	if got := byName["_System_AuditLog"].columns["FieldHistoryEligible"]; got != "TINYINT(1)" {
		t.Fatalf("_System_AuditLog.FieldHistoryEligible type = %q, want TINYINT(1)", got)
	}
	sequence := byName["_System_FieldHistorySequence"]
	if got := sequence.columns["CurrentSequence"]; got != "BIGINT" {
		t.Fatalf("_System_FieldHistorySequence.CurrentSequence type = %q, want BIGINT", got)
	}
	if sequence.foreignKeys != 0 {
		t.Fatalf("_System_FieldHistorySequence foreign keys = %d, want durable authority independent of field lifecycle", sequence.foreignKeys)
	}
	interval := byName["_System_FieldHistoryTrackingInterval"]
	if !reflect.DeepEqual(interval.indices["uk_field_history_open"], []string{"OpenFieldId"}) || !interval.indexUnique["uk_field_history_open"] {
		t.Fatalf("open interval unique index = %v unique=%t", interval.indices["uk_field_history_open"], interval.indexUnique["uk_field_history_open"])
	}
	if !reflect.DeepEqual(interval.indices["idx_field_history_interval"], []string{"FieldId", "StartedSequence", "EndedSequence"}) {
		t.Fatalf("interval lookup index = %v", interval.indices["idx_field_history_interval"])
	}
	if got := byName["_System_AuditLog"].indices["idx_history_temporal_eligibility"]; !reflect.DeepEqual(got, []string{"ObjectApiName", "RecordId", "FieldName", "HistorySequence"}) {
		t.Fatalf("audit temporal index = %v", got)
	}
	if got := byName["_System_AuditLog"].indices["idx_history_changed_at"]; !reflect.DeepEqual(got, []string{"ObjectApiName", "RecordId", "FieldName", "ChangedAt"}) {
		t.Fatalf("audit changed-at index = %v", got)
	}
	if got := byName["_System_AuditLog"].indices["idx_audit_retention_changed_at"]; !reflect.DeepEqual(got, []string{"ChangedAt", "Id"}) {
		t.Fatalf("audit retention index = %v", got)
	}
	for _, definition := range defs {
		if definition.TableName == "_System_AuditLog" {
			if definition.RetentionMaxRows != 0 || definition.RetentionMaxAgeSeconds != 0 || definition.RetentionMaxAgeMonths != 78 {
				t.Fatalf("audit retention = rows %d seconds %d months %d, want 0/0/78", definition.RetentionMaxRows, definition.RetentionMaxAgeSeconds, definition.RetentionMaxAgeMonths)
			}
			return
		}
	}
	t.Fatal("_System_AuditLog definition not found")
}
