package packs

import (
	"context"
	"errors"
	"reflect"
	"strings"
	"testing"

	cp "github.com/pingcap-inc/nexuscrm-contract/pkg/controlplane"
)

func TestFreezeSourceBackedExecutionAtomRejectsInvalidTargets(t *testing.T) {
	tests := []struct {
		name   string
		target *SourceBackedPack
		want   string
	}{
		{name: "nil", want: "target is nil"},
		{name: "zero", target: &SourceBackedPack{}, want: "target is incomplete"},
		{
			name: "empty name",
			target: &SourceBackedPack{
				source: &ResolvedPackSource{}, manifest: &PackManifest{Category: AppPack}, constructionComplete: true,
			},
			want: "target name is empty",
		},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			atom, err := FreezeSourceBackedExecutionAtom(test.target)
			if err == nil || !strings.Contains(err.Error(), test.want) {
				t.Fatalf("error = %v, want containing %q", err, test.want)
			}
			if atom != nil {
				t.Fatalf("atom = %#v, want a real nil pointer", atom)
			}
		})
	}
}

func TestSourceBackedExecutionAtomRejectsUnmintedValues(t *testing.T) {
	for name, atom := range map[string]*SourceBackedExecutionAtom{
		"nil":                     nil,
		"zero":                    {},
		"forged minted flag only": {minted: true},
		"forged identity":         {identity: &SourceBackedPackIdentity{}, minted: true},
	} {
		t.Run(name, func(t *testing.T) {
			if _, err := atom.Facts(); err == nil {
				t.Fatal("Facts error = nil, want unminted rejection")
			}
			if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err == nil {
				t.Fatal("Execute error = nil, want unminted rejection")
			}
			if err := atom.Verify(context.Background(), VerifyDeps{}); err == nil {
				t.Fatal("Verify error = nil, want unminted rejection")
			}
			if err := ValidateSourceBackedExecutionAtomTarget(atom, &SourceBackedPack{}); err == nil {
				t.Fatal("ValidateSourceBackedExecutionAtomTarget error = nil, want unminted rejection")
			}
		})
	}
}

func TestValidateSourceBackedExecutionAtomTargetRequiresExactTarget(t *testing.T) {
	target := executionAtomTestPack(t)
	atom, err := FreezeSourceBackedExecutionAtom(target)
	if err != nil {
		t.Fatalf("freeze: %v", err)
	}
	if err := ValidateSourceBackedExecutionAtomTarget(atom, target); err != nil {
		t.Fatalf("validate exact target: %v", err)
	}
	if err := ValidateSourceBackedExecutionAtomTarget(atom, nil); err == nil || !strings.Contains(err.Error(), "target is nil") {
		t.Fatalf("nil target error = %v, want nil-target rejection", err)
	}

	substitute := executionAtomTestPack(t)
	wantFacts, err := atom.Facts()
	if err != nil {
		t.Fatalf("atom facts: %v", err)
	}
	substituteAtom, err := FreezeSourceBackedExecutionAtom(substitute)
	if err != nil {
		t.Fatalf("freeze substitute: %v", err)
	}
	substituteFacts, err := substituteAtom.Facts()
	if err != nil {
		t.Fatalf("substitute facts: %v", err)
	}
	if substituteFacts != wantFacts {
		t.Fatalf("substitute facts = %#v, want facts-identical target %#v", substituteFacts, wantFacts)
	}
	if err := ValidateSourceBackedExecutionAtomTarget(atom, substitute); err == nil || !strings.Contains(err.Error(), "different target") {
		t.Fatalf("substitute target error = %v, want exact-pointer rejection", err)
	}

	original := *target
	*target = *substitute
	if err := ValidateSourceBackedExecutionAtomTarget(atom, target); err == nil || !strings.Contains(err.Error(), "different target") {
		t.Fatalf("in-place substitute error = %v, want construction-identity rejection", err)
	}
	*target = SourceBackedPack{}
	if err := ValidateSourceBackedExecutionAtomTarget(atom, target); err == nil || !strings.Contains(err.Error(), "different target") {
		t.Fatalf("in-place zeroing error = %v, want construction-identity rejection", err)
	}
	*target = original
	if err := ValidateSourceBackedExecutionAtomTarget(atom, target); err != nil {
		t.Fatalf("validate restored exact target: %v", err)
	}
}

func TestFreezeSourceBackedExecutionAtomCapturesDetachedFacts(t *testing.T) {
	pack := executionAtomTestPack(t)
	want := SourceBackedExecutionFacts{
		Name:     pack.Name(),
		Category: pack.Category(),
		Metadata: PackHashMetadataForPack(pack),
	}
	var err error
	want.PayloadHash, err = PackPayloadHash(pack)
	if err != nil {
		t.Fatalf("payload hash: %v", err)
	}
	want.HostRequirementsDigest, err = PackHostRequirementsDigest(pack)
	if err != nil {
		t.Fatalf("host requirements digest: %v", err)
	}

	atom, err := FreezeSourceBackedExecutionAtom(pack)
	if err != nil {
		t.Fatalf("freeze: %v", err)
	}
	pack.manifest.Name = "mutated"
	pack.manifest.Category = ConnectorPack
	pack.source.URI = "mutated"
	got, err := atom.Facts()
	if err != nil {
		t.Fatalf("Facts: %v", err)
	}
	if got != want {
		t.Fatalf("Facts = %#v, want %#v", got, want)
	}
	got.Name = "caller mutation"
	again, err := atom.Facts()
	if err != nil || again != want {
		t.Fatalf("Facts after caller mutation = %#v, %v; want %#v", again, err, want)
	}
}

func TestSourceBackedExecutionAtomRetainsOneInstallPlan(t *testing.T) {
	pack := executionAtomTestPack(t)
	var applied []string
	dependencyReads := 0
	original := &executionAtomTestComponent{key: "original", applied: &applied, dependencyReads: &dependencyReads}
	pack.components = []PackComponent{original}

	atom, err := FreezeSourceBackedExecutionAtom(pack)
	if err != nil {
		t.Fatalf("freeze: %v", err)
	}
	if dependencyReads != 2 {
		t.Fatalf("dependency reads during hash and plan construction = %d, want 2", dependencyReads)
	}
	pack.components = []PackComponent{&executionAtomTestComponent{key: "replacement", applied: &applied}}

	contract, _ := ComponentKindContractFor(ComponentKindObjectSpec)
	var phases []InstallPlanPhase
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{
		AfterPhase: func(_ context.Context, phase InstallPlanPhase) error {
			phases = append(phases, phase)
			return nil
		},
	}); err != nil {
		t.Fatalf("Execute: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"original"}) {
		t.Fatalf("applied = %v, want retained original", applied)
	}
	if !reflect.DeepEqual(phases, []InstallPlanPhase{contract.Phase}) {
		t.Fatalf("phases = %v, want [%s]", phases, contract.Phase)
	}
	if dependencyReads != 2 {
		t.Fatalf("dependency reads after execution = %d, want retained plan without rebuild", dependencyReads)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomWritesOnlyChangedComponentsAndVerifiesWholeTarget(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{key: "unchanged", payload: "same"},
		&executionAtomTestComponent{key: "changed", payload: "before"},
	}
	var applied, verified, lifecycleApplied, lifecycleVerified []string
	target := executionAtomTestPack(t)
	target.components = []PackComponent{
		&executionAtomTestComponent{key: "unchanged", payload: "same", applied: &applied, verified: &verified},
		&executionAtomTestComponent{key: "changed", payload: "after", applied: &applied, verified: &verified},
	}
	target.sweepComponents = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindStandardFlow, key: "always-run", applied: &lifecycleApplied, verified: &lifecycleVerified},
	}

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if len(delta.Changed) != 1 || delta.Changed[0].BusinessKey != "changed" || delta.UnchangedCount != 1 {
		t.Fatalf("delta = %#v, want one changed and one unchanged component", delta)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute delta: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"changed"}) {
		t.Fatalf("applied = %v, want only changed component", applied)
	}
	if len(lifecycleApplied) != 0 {
		t.Fatalf("lifecycle applied = %v, want untouched kind skipped", lifecycleApplied)
	}
	if err := atom.Verify(context.Background(), VerifyDeps{}); err != nil {
		t.Fatalf("verify delta: %v", err)
	}
	if !reflect.DeepEqual(verified, []string{"unchanged", "changed"}) {
		t.Fatalf("verified = %v, want complete target pack verification", verified)
	}
	if !reflect.DeepEqual(lifecycleVerified, []string{"always-run"}) {
		t.Fatalf("lifecycle verified = %v, want always-run closure", lifecycleVerified)
	}
}

func TestFreezeSourceBackedRetryExecutionAtomReplaysCompleteTargetAfterPartialFailure(t *testing.T) {
	var applied []string
	var verified []string
	target := executionAtomTestPack(t)
	target.components = []PackComponent{
		&executionAtomTestComponent{key: "unchanged-but-live-drifted", payload: "same", applied: &applied, verified: &verified},
		&executionAtomTestComponent{key: "changed-before-failure", payload: "new", applied: &applied, verified: &verified},
	}

	atom, err := FreezeSourceBackedRetryExecutionAtom(target)
	if err != nil {
		t.Fatalf("freeze retry atom: %v", err)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute retry atom: %v", err)
	}
	if err := atom.Verify(context.Background(), VerifyDeps{}); err != nil {
		t.Fatalf("verify retry atom: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"unchanged-but-live-drifted", "changed-before-failure"}) {
		t.Fatalf("applied = %v, want complete target replay", applied)
	}
	if !reflect.DeepEqual(verified, []string{"unchanged-but-live-drifted", "changed-before-failure"}) {
		t.Fatalf("verified = %v, want complete target verification", verified)
	}
}

func TestFreezeSourceBackedReplayExecutionAtomReplaysCompleteTargetAndRetainsDropToZero(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindObjectSpec, key: "unchanged", payload: "same"},
		&executionAtomTestComponent{kind: ComponentKindApprovalProcess, key: "removed", payload: "old"},
	}
	target := executionAtomTestPack(t)
	target.componentRegistrationSet = executionAtomExactSetRegistrationSet(t)
	target.componentRegistrationSetConfigured = true
	target.components = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindObjectSpec, key: "unchanged", payload: "same"},
	}

	atom, delta, err := FreezeSourceBackedReplayExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze replay atom: %v", err)
	}
	if len(delta.Removed) != 1 || delta.Removed[0].Kind != ComponentKindApprovalProcess {
		t.Fatalf("delta = %#v, want the removed exact-set declaration", delta)
	}
	components := installPlanComponents(atom.plan)
	if len(components) != 2 {
		t.Fatalf("retained components = %d, want complete target plus transition lifecycle", len(components))
	}
	if components[0].Kind() != ComponentKindObjectSpec || components[0].BusinessKey() != "unchanged" {
		t.Fatalf("first retained component = %s/%s, want unchanged target replay", components[0].Kind(), components[0].BusinessKey())
	}
	if _, ok := components[1].(*sourceBackedExternalManagedSetComponent); !ok {
		t.Fatalf("second retained component = %#v, want transition-proven exact set", components[1])
	}
	verifiedSet := false
	for _, component := range atom.verify {
		if _, ok := component.(*sourceBackedExternalManagedSetComponent); ok {
			verifiedSet = true
		}
	}
	if !verifiedSet {
		t.Fatal("replay atom omitted transition-proven exact set from final verification")
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomSkipsUnchangedPrerequisitesAndReplaysDependents(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{key: "prerequisite", payload: "same"},
		&executionAtomTestComponent{key: "changed", payload: "before"},
		&executionAtomTestComponent{key: "dependent", payload: "same"},
	}
	var applied []string
	target := executionAtomTestPack(t)
	target.components = []PackComponent{
		&executionAtomTestComponent{key: "prerequisite", payload: "same", applied: &applied},
		&executionAtomTestComponent{
			key: "changed", payload: "after", applied: &applied,
			dependencies: []ComponentReference{{Kind: ComponentKindObjectSpec, BusinessKey: "prerequisite", Required: true}},
		},
		&executionAtomTestComponent{
			key: "dependent", payload: "same", applied: &applied,
			dependencies: []ComponentReference{{Kind: ComponentKindObjectSpec, BusinessKey: "changed", Required: true}},
		},
	}

	atom, _, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute delta: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"changed", "dependent"}) {
		t.Fatalf("applied = %v, want changed component and its dependent without unchanged prerequisite", applied)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomRetainsCompleteApplyGroup(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{key: "changed", payload: "before", group: "batch"},
		&executionAtomTestComponent{key: "group-peer", payload: "same", group: "batch"},
	}
	var applied []string
	target := executionAtomTestPack(t)
	target.components = []PackComponent{
		&executionAtomTestComponent{key: "changed", payload: "after", applied: &applied, group: "batch"},
		&executionAtomTestComponent{key: "group-peer", payload: "same", applied: &applied, group: "batch"},
	}

	atom, _, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute delta: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"changed"}) {
		t.Fatalf("applied = %v, want one complete batch execution", applied)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomDoesNotResetUnchangedListFieldsForFlowOnlyChange(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindObjectSpec, key: "standard_objects_spec:crm", payload: "same-object"},
		&executionAtomTestComponent{
			kind: ComponentKindListFields, key: "standard_listfields", payload: "same-list-fields",
			dependencies: []ComponentReference{{Kind: ComponentKindObjectSpec, BusinessKey: "standard_objects_spec:crm", Required: true}},
		},
		&executionAtomTestComponent{
			kind: ComponentKindStandardFlow, key: "LeadFlow", payload: "before",
			dependencies: []ComponentReference{{Kind: ComponentKindObjectSpec, BusinessKey: "standard_objects_spec:crm", Required: true}},
		},
	}
	var applied []string
	target := executionAtomTestPack(t)
	target.components = []PackComponent{
		&executionAtomTestComponent{
			kind: ComponentKindObjectSpec, key: "standard_objects_spec:crm", payload: "same-object", applied: &applied,
		},
		&executionAtomTestComponent{
			kind: ComponentKindListFields, key: "standard_listfields", payload: "same-list-fields", applied: &applied,
			dependencies: []ComponentReference{{Kind: ComponentKindObjectSpec, BusinessKey: "standard_objects_spec:crm", Required: true}},
		},
		&executionAtomTestComponent{
			kind: ComponentKindStandardFlow, key: "LeadFlow", payload: "after", applied: &applied,
			dependencies: []ComponentReference{{Kind: ComponentKindObjectSpec, BusinessKey: "standard_objects_spec:crm", Required: true}},
		},
	}

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if len(delta.Changed) != 1 || delta.Changed[0].Kind != ComponentKindStandardFlow {
		t.Fatalf("delta = %#v, want only changed standard flow", delta)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute delta: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"LeadFlow"}) {
		t.Fatalf("applied = %v, want flow-only write without object_spec/ListFields reset", applied)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomRetainsKindSweeperForRemoval(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindStandardFlow, key: "removed", payload: "old"},
	}
	var applied []string
	target := executionAtomTestPack(t)
	target.sweepComponents = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindStandardFlow, key: "_pack_sweep_standard_flow", payload: "desired-empty", applied: &applied},
	}

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if len(delta.Removed) != 1 {
		t.Fatalf("delta = %#v, want one removal served by sweeper", delta)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute delta: %v", err)
	}
	if !reflect.DeepEqual(applied, []string{"_pack_sweep_standard_flow"}) {
		t.Fatalf("applied = %v, want only standard-flow sweeper", applied)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomRejectsRemovalWithoutLifecycleOwner(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindObjectSpec, key: "removed", payload: "old"},
	}
	target := executionAtomTestPack(t)

	atom, _, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err == nil || !strings.Contains(err.Error(), "has no lifecycle owner") {
		t.Fatalf("freeze error = %v, want missing lifecycle owner rejection", err)
	}
	if atom != nil {
		t.Fatalf("atom = %#v, want nil on unowned removal", atom)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomNoopWritesNothingAndVerifiesWholeTarget(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{&executionAtomTestComponent{key: "same", payload: "same"}}
	target := executionAtomTestPack(t)
	var declaredApplied, declaredVerified, lifecycleApplied, lifecycleVerified []string
	target.components = []PackComponent{&executionAtomTestComponent{key: "same", payload: "same", applied: &declaredApplied, verified: &declaredVerified}}
	target.sweepComponents = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindStandardFlow, key: "always-run", applied: &lifecycleApplied, verified: &lifecycleVerified},
	}

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if !delta.IsNoop() || delta.UnchangedCount != 1 {
		t.Fatalf("delta = %#v, want no-op", delta)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute no-op delta: %v", err)
	}
	if len(declaredApplied) != 0 {
		t.Fatalf("declared applied = %v, want unchanged declaration skipped", declaredApplied)
	}
	if len(lifecycleApplied) != 0 {
		t.Fatalf("lifecycle applied = %v, want unchanged lifecycle skipped", lifecycleApplied)
	}
	if err := atom.Verify(context.Background(), VerifyDeps{}); err != nil {
		t.Fatalf("verify no-op delta: %v", err)
	}
	if !reflect.DeepEqual(declaredVerified, []string{"same"}) {
		t.Fatalf("declared verified = %v, want unchanged declaration verified", declaredVerified)
	}
	if !reflect.DeepEqual(lifecycleVerified, []string{"always-run"}) {
		t.Fatalf("lifecycle verified = %v, want always-run closure", lifecycleVerified)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomNoopSurfacesLifecycleDriftDuringVerification(t *testing.T) {
	current := executionAtomTestPack(t)
	target := executionAtomTestPack(t)
	lifecycleErr := errors.New("lifecycle sentinel")
	target.sweepComponents = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindStandardFlow, key: "always-run", verifyErr: lifecycleErr},
	}

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if !delta.IsNoop() {
		t.Fatalf("delta = %#v, want declared-component no-op", delta)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute no-op delta: %v", err)
	}
	if err := atom.Verify(context.Background(), VerifyDeps{}); !errors.Is(err, lifecycleErr) {
		t.Fatalf("verify error = %v, want lifecycle sentinel", err)
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomNoopSkipsExternalManagedSetWrite(t *testing.T) {
	current := executionAtomTestPack(t)
	target := executionAtomTestPack(t)
	target.componentRegistrationSet = executionAtomExactSetRegistrationSet(t)
	target.componentRegistrationSetConfigured = true

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if !delta.IsNoop() {
		t.Fatalf("delta = %#v, want declared-component no-op", delta)
	}
	components := installPlanComponents(atom.plan)
	if len(components) != 0 {
		t.Fatalf("retained components = %d, want no write plan for unchanged managed set", len(components))
	}
}

func TestFreezeSourceBackedDeltaExecutionAtomUsesExternalManagedSetForRemoval(t *testing.T) {
	current := executionAtomTestPack(t)
	current.components = []PackComponent{
		&executionAtomTestComponent{kind: ComponentKindApprovalProcess, key: "removed", payload: "old"},
	}
	target := executionAtomTestPack(t)
	target.componentRegistrationSet = executionAtomExactSetRegistrationSet(t)
	target.componentRegistrationSetConfigured = true

	atom, delta, err := FreezeSourceBackedDeltaExecutionAtom(current, target)
	if err != nil {
		t.Fatalf("freeze delta: %v", err)
	}
	if len(delta.Removed) != 1 {
		t.Fatalf("delta = %#v, want one removal served by managed-set lifecycle", delta)
	}
	components := installPlanComponents(atom.plan)
	if len(components) != 1 {
		t.Fatalf("retained components = %d, want one managed-set lifecycle component", len(components))
	}
	if _, ok := components[0].(*sourceBackedExternalManagedSetComponent); !ok {
		t.Fatalf("retained component = %#v, want managed-set lifecycle", components[0])
	}
	verifiedSet := false
	for _, component := range atom.verify {
		if _, ok := component.(*sourceBackedExternalManagedSetComponent); ok {
			verifiedSet = true
		}
	}
	if !verifiedSet {
		t.Fatal("drop-to-zero delta omitted exact-set verification from the final receipt")
	}
}

func executionAtomExactSetRegistrationSet(t *testing.T) ComponentKindRegistrationSet {
	t.Helper()
	base := testComponentKindRegistration(cp.ComponentKindApprovalProcess, "ProcessDefinition")
	base.ManagedProvider = nil
	original := testComponentManagedLifecycleRegistration(t, cp.ComponentKindApprovalProcess, "ProcessDefinition")
	lifecycle, err := cp.NewComponentManagedLifecycleRegistration(cp.ComponentManagedLifecycleRegistrationSpec{
		Kind:            original.Kind(),
		ReadSet:         original.ReadSet(),
		Capabilities:    append(original.Capabilities(), cp.ComponentManagedCapabilityExactSet),
		EffectClasses:   original.EffectClasses(),
		TransactionMode: original.TransactionMode(),
		Budget:          original.Budget(),
		Lifecycle:       original.Lifecycle(),
	})
	if err != nil {
		t.Fatalf("exact-set lifecycle: %v", err)
	}
	bound, err := base.WithManagedLifecycle(lifecycle)
	if err != nil {
		t.Fatalf("bind exact-set lifecycle: %v", err)
	}
	set, err := NewComponentKindRegistrationSetWithManagedLifecycles(nil, []cp.ComponentKindManagedLifecycleRegistration{bound})
	if err != nil {
		t.Fatalf("registration set: %v", err)
	}
	return set
}

func TestSourceBackedExecutionAtomPreservesExecutionErrors(t *testing.T) {
	applyErr := errors.New("apply sentinel")
	pack := executionAtomTestPack(t)
	pack.components = []PackComponent{&executionAtomTestComponent{key: "apply", applyErr: applyErr}}
	atom, err := FreezeSourceBackedExecutionAtom(pack)
	if err != nil {
		t.Fatalf("freeze apply atom: %v", err)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); !errors.Is(err, applyErr) {
		t.Fatalf("Execute error = %v, want errors.Is apply sentinel", err)
	}

	hookErr := errors.New("hook sentinel")
	pack = executionAtomTestPack(t)
	pack.components = []PackComponent{&executionAtomTestComponent{key: "hook"}}
	atom, err = FreezeSourceBackedExecutionAtom(pack)
	if err != nil {
		t.Fatalf("freeze hook atom: %v", err)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{
		AfterPhase: func(context.Context, InstallPlanPhase) error { return hookErr },
	}); !errors.Is(err, hookErr) {
		t.Fatalf("Execute error = %v, want errors.Is hook sentinel", err)
	}
}

func TestFreezeSourceBackedExecutionAtomAcceptsEmptyPlanAndRejectsPlanErrors(t *testing.T) {
	pack := executionAtomTestPack(t)
	atom, err := FreezeSourceBackedExecutionAtom(pack)
	if err != nil {
		t.Fatalf("freeze empty plan: %v", err)
	}
	if err := atom.Execute(context.Background(), ApplyDeps{}, InstallPlanHooks{}); err != nil {
		t.Fatalf("execute empty plan: %v", err)
	}

	pack = executionAtomTestPack(t)
	pack.components = []PackComponent{&executionAtomTestComponent{kind: ComponentKind("unknown"), key: "bad"}}
	atom, err = FreezeSourceBackedExecutionAtom(pack)
	if err == nil || !strings.Contains(err.Error(), "install plan") {
		t.Fatalf("plan error = %v, want install-plan rejection", err)
	}
	if atom != nil {
		t.Fatalf("atom = %#v, want nil on plan error", atom)
	}
}

func TestSourceBackedExecutionAtomExposesNoPackOrPlanSurfaces(t *testing.T) {
	atom, err := FreezeSourceBackedExecutionAtom(executionAtomTestPack(t))
	if err != nil {
		t.Fatalf("freeze: %v", err)
	}
	type phasesAccessor interface{ Phases() []InstallPlanPhase }
	type componentsAccessor interface {
		ComponentsForPhase(InstallPlanPhase) []PackComponent
	}
	interfaces := map[string]reflect.Type{
		"Pack":                                     reflect.TypeOf((*Pack)(nil)).Elem(),
		"ComposablePack":                           reflect.TypeOf((*ComposablePack)(nil)).Elem(),
		"PayloadHasher":                            reflect.TypeOf((*PayloadHasher)(nil)).Elem(),
		"LegacyPayloadHasher":                      reflect.TypeOf((*LegacyPayloadHasher)(nil)).Elem(),
		"PackHashMetadataProvider":                 reflect.TypeOf((*PackHashMetadataProvider)(nil)).Elem(),
		"PackDependencyProvider":                   reflect.TypeOf((*PackDependencyProvider)(nil)).Elem(),
		"ComponentDeclarer":                        reflect.TypeOf((*ComponentDeclarer)(nil)).Elem(),
		"HostRequirementsProvider":                 reflect.TypeOf((*HostRequirementsProvider)(nil)).Elem(),
		"runtimeMetadataProvider":                  reflect.TypeOf((*runtimeMetadataProvider)(nil)).Elem(),
		"runtimeSearchScopeOrderProvider":          reflect.TypeOf((*runtimeSearchScopeOrderProvider)(nil)).Elem(),
		"runtimeRelatedListRuleProvider":           reflect.TypeOf((*runtimeRelatedListRuleProvider)(nil)).Elem(),
		"runtimeStartupShallowDeclarationProvider": reflect.TypeOf((*runtimeStartupShallowDeclarationProvider)(nil)).Elem(),
		"runtimeSearchAllDefaultFieldsProvider":    reflect.TypeOf((*runtimeSearchAllDefaultFieldsProvider)(nil)).Elem(),
		"runtimeFormulaFunctionBundleProvider":     reflect.TypeOf((*runtimeFormulaFunctionBundleProvider)(nil)).Elem(),
		"runtimeHrefRewriteFieldsProvider":         reflect.TypeOf((*runtimeHrefRewriteFieldsProvider)(nil)).Elem(),
		"Phases accessor":                          reflect.TypeOf((*phasesAccessor)(nil)).Elem(),
		"ComponentsForPhase accessor":              reflect.TypeOf((*componentsAccessor)(nil)).Elem(),
	}
	candidate := reflect.TypeOf(atom)
	for name, iface := range interfaces {
		if candidate.Implements(iface) {
			t.Errorf("execution atom unexpectedly implements %s", name)
		}
	}
}

func executionAtomTestPack(t *testing.T) *SourceBackedPack {
	t.Helper()
	pack := testSourceBackedPack(t, nil, nil)
	pack.components = nil
	pack.sweepComponents = nil
	return pack
}

type executionAtomTestComponent struct {
	kind            ComponentKind
	key             string
	payload         string
	group           string
	dependencies    []ComponentReference
	applied         *[]string
	verified        *[]string
	applyErr        error
	verifyErr       error
	dependencyReads *int
}

func (c *executionAtomTestComponent) Kind() ComponentKind {
	if c.kind != "" {
		return c.kind
	}
	return ComponentKindObjectSpec
}
func (c *executionAtomTestComponent) PackName() string             { return "jira-like-sample" }
func (c *executionAtomTestComponent) BusinessKey() string          { return c.key }
func (c *executionAtomTestComponent) Manageability() Manageability { return ManageabilityLocked }
func (c *executionAtomTestComponent) ExpectedPayload() ([]byte, error) {
	payload := c.payload
	if payload == "" {
		payload = c.key
	}
	return []byte(`{"value":"` + payload + `"}`), nil
}
func (c *executionAtomTestComponent) ExpectedProjection() (any, error) { return nil, nil }
func (c *executionAtomTestComponent) LiveProjection(context.Context, VerifyDeps) (any, error) {
	if c.verified != nil {
		*c.verified = append(*c.verified, c.key)
	}
	return nil, c.verifyErr
}
func (c *executionAtomTestComponent) Apply(context.Context, ApplyDeps) error {
	if c.applied != nil {
		*c.applied = append(*c.applied, c.key)
	}
	return c.applyErr
}
func (c *executionAtomTestComponent) DependsOn() []ComponentReference {
	if c.dependencyReads != nil {
		(*c.dependencyReads)++
	}
	return append([]ComponentReference(nil), c.dependencies...)
}
func (c *executionAtomTestComponent) ApplyGroupKey() string { return c.group }
