package pipeline

import (
	"context"
	"testing"

	"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
)

type retryingNotesNormalizer struct {
	retry *contracts.NormalizeRetry
}

func (retryingNotesNormalizer) Key() string                               { return "test/retry-normalize" }
func (retryingNotesNormalizer) ReferenceSlots() []contracts.ReferenceSlot { return nil }
func (n retryingNotesNormalizer) Normalize(_ context.Context, req contracts.TypedNormalizeRequest[codecNotes]) (contracts.TypedNormalizeResult[codecNotes], error) {
	return contracts.TypedNormalizeResult[codecNotes]{Value: req.MergeOutput.Value, Retry: n.retry}, nil
}

func TestNormalizerRegistryErasureClonesRetryDirective(t *testing.T) {
	retry := &contracts.NormalizeRetry{
		ReasonCode:         "retryable",
		Message:            "safe fallback available",
		CorrectionGuidance: "return a complete corrected proposal",
	}
	registry := NewNormalizerRegistry()
	if err := RegisterNormalizer(registry, ModuleSpec{Key: "test/retry-normalize", Stage: StageNormalize, ExecutionClass: contracts.ExecutionClassDeterministic, ArtifactKind: "test/notes"}, func() (contracts.Normalizer[codecNotes], error) {
		return retryingNotesNormalizer{retry: retry}, nil
	}); err != nil {
		t.Fatalf("RegisterNormalizer() error = %v", err)
	}
	entry, ok := registry.typedEntry("test/retry-normalize", "test/notes")
	if !ok {
		t.Fatal("typed normalizer entry missing")
	}
	implementation, err := entry.builder(BuildRequest{})
	if err != nil {
		t.Fatalf("builder() error = %v", err)
	}
	result, err := entry.normalize(context.Background(), implementation, contracts.TypedNormalizeRequest[any]{MergeOutput: contracts.MergeArtifact[any]{Value: codecNotes{Items: []string{"safe"}}}})
	if err != nil {
		t.Fatalf("normalize() error = %v", err)
	}
	retry.Message = "mutated"
	retry.CorrectionGuidance = "mutated guidance"
	if result.Retry == nil || result.Retry.Message != "safe fallback available" || result.Retry.CorrectionGuidance != "return a complete corrected proposal" {
		t.Fatalf("erased retry result = %#v, want independent retry data", result)
	}
}
