package iace

import (
	"strings"
	"testing"
)

// BuildArchitecture is the data-driven engine self-description rendered in the
// "Architektur & Datenfluss" auditability tab. These tests pin its shape and,
// crucially, that the library counts are LIVE (non-zero, drawn from the running
// engine) — a zero count would mean the diagram silently drifted from reality.

func TestBuildArchitecture_Shape(t *testing.T) {
	a := BuildArchitecture()

	if len(a.Stages) != 10 {
		t.Errorf("expected 10 pipeline stages, got %d", len(a.Stages))
	}
	// Stage order is the audit narrative — first is the limits form, last the matrix.
	if len(a.Stages) > 0 && a.Stages[0].ID != "grenzen" {
		t.Errorf("first stage should be grenzen, got %q", a.Stages[0].ID)
	}
	if last := a.Stages[len(a.Stages)-1]; last.ID != "matrix" {
		t.Errorf("last stage should be matrix, got %q", last.ID)
	}
	for _, s := range a.Stages {
		if s.Title == "" || s.Summary == "" || s.Logic == "" || s.DataSource == "" {
			t.Errorf("stage %q has empty required prose: %+v", s.ID, s)
		}
	}

	if len(a.NormMatching) == 0 {
		t.Error("norm_matching explanation must not be empty")
	}
	if len(a.Evidence) == 0 {
		t.Error("evidence (ESAW citations) must not be empty")
	}
}

func TestBuildArchitecture_LiveLibraryCounts(t *testing.T) {
	a := BuildArchitecture()

	if len(a.Libraries) == 0 {
		t.Fatal("no libraries reported")
	}
	for _, l := range a.Libraries {
		if l.Name == "" || l.SourceFile == "" {
			t.Errorf("library missing name/source: %+v", l)
		}
		if l.Count <= 0 {
			t.Errorf("library %q has non-live count %d (expected >0 from running engine)", l.Name, l.Count)
		}
	}
}

func TestBuildArchitecture_DataSourcesIncludeExclusions(t *testing.T) {
	a := BuildArchitecture()

	var hasUsed, hasExcluded bool
	for _, d := range a.DataSources {
		switch d.Status {
		case "verwendet":
			hasUsed = true
		case "ausgeschlossen":
			hasExcluded = true
		default:
			t.Errorf("data source %q has unexpected status %q", d.Name, d.Status)
		}
		if d.License == "" {
			t.Errorf("data source %q missing license", d.Name)
		}
	}
	if !hasUsed {
		t.Error("expected at least one used data source")
	}
	// The copyright guardrail is auditable only if the EXCLUDED norm tables are
	// shown as deliberately not-reproduced — not silently omitted.
	if !hasExcluded {
		t.Error("expected DIN/Beuth norm tables to appear as an explicit exclusion")
	}

	// The licensing guardrail must be spelled out in the norm-matching prose:
	// norm tables are referenced, never reproduced.
	joined := strings.ToLower(strings.Join(a.NormMatching, " "))
	if !strings.Contains(joined, "reproduziert") {
		t.Error("norm-matching prose should state norm tables are never reproduced")
	}
}
