package ucca

import (
	"testing"
)

func TestTOMControlLoader(t *testing.T) {
	index, err := LoadTOMControls()
	if err != nil {
		t.Skipf("TOM controls not found: %v", err)
	}

	if len(index.ByID) == 0 {
		t.Error("expected controls indexed by ID")
	}
	if len(index.ByDomain) == 0 {
		t.Error("expected controls indexed by domain")
	}
	t.Logf("Loaded %d TOM controls across %d domains", len(index.ByID), len(index.ByDomain))

	// Check known control
	ctrl, ok := index.GetControl("TOM.GOV.01")
	if !ok || ctrl == nil {
		t.Error("expected TOM.GOV.01 to exist")
	} else if ctrl.Title == "" {
		t.Error("expected TOM.GOV.01 to have a title")
	}

	// Check domain
	govCtrls := index.GetControlsByDomain("GOV")
	if len(govCtrls) == 0 {
		t.Error("expected GOV domain to have controls")
	}

	// Validate known ID
	if !index.ValidateControlID("TOM.GOV.01") {
		t.Error("TOM.GOV.01 should be valid")
	}
	if index.ValidateControlID("TOM.FAKE.99") {
		t.Error("TOM.FAKE.99 should be invalid")
	}
}

func TestTOMObligationMapper_FromObligations(t *testing.T) {
	index, err := LoadTOMControls()
	if err != nil {
		t.Skipf("TOM controls not found: %v", err)
	}

	// Create test obligations with tom_control_ids
	obligations := []V2Obligation{
		{
			ID:            "TEST-OBL-001",
			TOMControlIDs: []string{"TOM.GOV.01", "TOM.GOV.02"},
			Priority:      "kritisch",
		},
		{
			ID:            "TEST-OBL-002",
			TOMControlIDs: []string{"TOM.GOV.01", "TOM.CRYPTO.01"},
			Priority:      "hoch",
		},
	}

	mapper := NewTOMObligationMapperFromObligations(index, obligations)

	// Check obligation->control
	controls := mapper.GetControlsForObligation("TEST-OBL-001")
	if len(controls) != 2 {
		t.Errorf("expected 2 controls for TEST-OBL-001, got %d", len(controls))
	}

	// Check control->obligation (reverse)
	oblIDs := mapper.GetObligationsForControl("TOM.GOV.01")
	if len(oblIDs) != 2 {
		t.Errorf("expected 2 obligations for TOM.GOV.01, got %d", len(oblIDs))
	}

	// Check deduplicated requirements
	frameworkObls := make([]Obligation, len(obligations))
	for i, o := range obligations {
		frameworkObls[i] = Obligation{
			ID:                o.ID,
			Priority:          ObligationPriority(o.Priority),
			ExternalResources: o.TOMControlIDs,
		}
	}
	reqs := mapper.DeriveControlsFromObligations(frameworkObls)
	if len(reqs) == 0 {
		t.Error("expected derived control requirements")
	}

	// GOV.01 should appear once but with 2 obligation references
	for _, req := range reqs {
		if req.Control != nil && req.Control.ID == "TOM.GOV.01" {
			if req.RequiredByCount != 2 {
				t.Errorf("expected TOM.GOV.01 required by 2, got %d", req.RequiredByCount)
			}
			if req.Priority != "kritisch" {
				t.Errorf("expected highest priority 'kritisch', got '%s'", req.Priority)
			}
			return
		}
	}
	t.Error("TOM.GOV.01 not found in derived requirements")
}

func TestTOMGapAnalysis(t *testing.T) {
	index, err := LoadTOMControls()
	if err != nil {
		t.Skipf("TOM controls not found: %v", err)
	}

	obligations := []V2Obligation{
		{ID: "T-001", TOMControlIDs: []string{"TOM.GOV.01"}, Priority: "kritisch"},
		{ID: "T-002", TOMControlIDs: []string{"TOM.GOV.01", "TOM.CRYPTO.01"}, Priority: "hoch"},
	}
	mapper := NewTOMObligationMapperFromObligations(index, obligations)
	analyzer := NewTOMGapAnalyzer(mapper, index)

	frameworkObls := []Obligation{
		{ID: "T-001", Priority: "kritisch", ExternalResources: []string{"TOM.GOV.01"}},
		{ID: "T-002", Priority: "hoch", ExternalResources: []string{"TOM.GOV.01", "TOM.CRYPTO.01"}},
	}

	result := analyzer.Analyze(&GapAnalysisRequest{
		Obligations: frameworkObls,
		ControlStatusMap: map[string]ControlStatus{
			"TOM.GOV.01":    ControlImplemented,
			"TOM.CRYPTO.01": ControlNotImplemented,
		},
	})

	if result.TotalControls != 2 {
		t.Errorf("expected 2 total controls, got %d", result.TotalControls)
	}
	if result.ImplementedControls != 1 {
		t.Errorf("expected 1 implemented, got %d", result.ImplementedControls)
	}
	if result.MissingControls != 1 {
		t.Errorf("expected 1 missing, got %d", result.MissingControls)
	}
	if result.CompliancePercent != 50 {
		t.Errorf("expected 50%% compliance, got %.1f%%", result.CompliancePercent)
	}
	if len(result.Gaps) != 1 {
		t.Errorf("expected 1 gap, got %d", len(result.Gaps))
	}
}

func TestTOMGapAnalysis_AllImplemented(t *testing.T) {
	index, err := LoadTOMControls()
	if err != nil {
		t.Skipf("TOM controls not found: %v", err)
	}

	obligations := []V2Obligation{
		{ID: "T-001", TOMControlIDs: []string{"TOM.GOV.01"}, Priority: "hoch"},
	}
	mapper := NewTOMObligationMapperFromObligations(index, obligations)
	analyzer := NewTOMGapAnalyzer(mapper, index)

	result := analyzer.Analyze(&GapAnalysisRequest{
		Obligations: []Obligation{{ID: "T-001", Priority: "hoch", ExternalResources: []string{"TOM.GOV.01"}}},
		ControlStatusMap: map[string]ControlStatus{
			"TOM.GOV.01": ControlImplemented,
		},
	})

	if result.CompliancePercent != 100 {
		t.Errorf("expected 100%% compliance, got %.1f%%", result.CompliancePercent)
	}
	if len(result.Gaps) != 0 {
		t.Errorf("expected 0 gaps, got %d", len(result.Gaps))
	}
}
