package iace

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

func TestVerifyPins(t *testing.T) {
	pins := []AcceptedPin{
		{Pattern: "HPa", MustFire: true},
		{Pattern: "HPb", MustFire: false},
	}
	res := VerifyPins(pins, []string{"HPa", "HPb"})
	if !res[0].OK {
		t.Errorf("HPa must_fire=true and it fired -> should be OK")
	}
	if res[1].OK {
		t.Errorf("HPb must_fire=false but it fired -> should be VIOLATED")
	}
	res2 := VerifyPins(pins, []string{})
	if res2[0].OK || !res2[1].OK {
		t.Errorf("expected HPa violated + HPb ok, got %+v", res2)
	}
}

func TestGenerateDedupPin(t *testing.T) {
	pin := GenerateDedupPin(DedupCandidate{KeepPattern: "HP144", DropPattern: "HP013", Category: "electrical_hazard"})
	if pin.Pattern != "HP013" || pin.MustFire {
		t.Fatalf("want pin {HP013, must_fire=false}, got %+v", pin)
	}
}

// TestWarewashing_AcceptedPins re-checks every accepted P1 supersession against the
// live warewashing engine output. A future change that un-suppresses HP013/016/018
// or drops HP2201/HP144 breaks a pin here — the gate compounds, not erodes.
func TestWarewashing_AcceptedPins(t *testing.T) {
	raw, err := os.ReadFile(filepath.Join("testdata", "accepted_pins_warewashing.json"))
	if err != nil {
		t.Fatalf("read pins: %v", err)
	}
	var ps PinSet
	if err := json.Unmarshal(raw, &ps); err != nil {
		t.Fatalf("parse pins: %v", err)
	}

	_, _, kept := warewashingEngineOutput()
	firedIDs := make([]string, 0, len(kept))
	for _, pm := range kept {
		firedIDs = append(firedIDs, pm.PatternID)
	}

	ok := 0
	for _, r := range VerifyPins(ps.Pins, firedIDs) {
		if r.OK {
			ok++
			continue
		}
		t.Errorf("PIN VIOLATED: %s (must_fire=%v) — %s [%s]", r.Pin.Pattern, r.Pin.MustFire, r.Detail, r.Pin.Reason)
	}
	t.Logf("accepted pins for %q: %d/%d hold", ps.Machine, ok, len(ps.Pins))
}
