package controlplane

import (
	"context"
	"database/sql"
	"reflect"
	"strings"
	"testing"

	"github.com/DATA-DOG/go-sqlmock"
	"github.com/nexuscrm/db"
	"github.com/nexuscrm/kernel/pkg/formula"
	"github.com/pingcap-inc/nexuscrm-controlplane/packs"
)

func TestResolveApplyAllSourceRevisionAdvanceInstalledTupleEmpty(t *testing.T) {
	emptyPrecondition := applyAllSourceRevisionAdvancePreconditionProof{
		snapshot: applyAllSourceRevisionAdvanceCurrentSnapshot{entries: []applyAllSourceRevisionAdvanceCurrentSnapshotEntry{}},
		current: applyAllSourceRevisionAdvanceTuple{
			plan: []normalizedApplyAllSourceRevisionAdvance{}, targets: map[string]*packs.SourceBackedPack{},
		},
	}
	source, err := resolveApplyAllSourceRevisionAdvanceSourceTuple(nil, packs.ComponentKindRegistrationSet{})
	if err != nil {
		t.Fatalf("resolve empty source tuple: %v", err)
	}
	tuple, err := resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(), nil, emptyPrecondition, source,
	)
	if err != nil {
		t.Fatalf("resolve empty installed tuple: %v", err)
	}
	if len(tuple.plan) != 0 || len(tuple.targets) != 0 || tuple.activeRuntimeIdentity != nil {
		t.Fatalf("empty tuple = %#v, want initialized empty plan and targets", tuple)
	}

	_, err = resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(), nil, emptyPrecondition, testApplyAllSourceRevisionAdvanceSourceTuple(applyAllSourceRevisionAdvanceTuple{
			plan:    []normalizedApplyAllSourceRevisionAdvance{},
			targets: map[string]*packs.SourceBackedPack{"extra": nil},
		}),
	)
	assertApplyAllSourceRevisionComposeError(t, err, -1, "")

	_, err = resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(), nil, emptyPrecondition, applyAllSourceRevisionAdvanceSourceTuple{},
	)
	assertApplyAllSourceRevisionComposeError(t, err, -1, "")

	_, err = resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(), nil, applyAllSourceRevisionAdvancePreconditionProof{}, source,
	)
	assertApplyAllSourceRevisionAdvancePreconditionError(
		t, err, ApplyAllSourceRevisionAdvancePlanState, -1, "",
	)
}

func TestResolveApplyAllSourceRevisionAdvanceInstalledTupleRequiresDatabase(t *testing.T) {
	advance := testApplyAllSourceRevisionAdvance("crm", 3)
	currentTarget := testApplyAllSourceRevisionTarget(t, "crm", "1.0.0", "official_repo", "crm", advance.FromRevision)
	precondition := testApplyAllSourceRevisionAdvanceFrozenCurrentTargetProof(
		t, advance, currentTarget, installedPackStatusActive, advance.Kind, testCurrentTargetV1Hash, nil,
	)
	sourceTuple := applyAllSourceRevisionAdvanceTuple{
		plan: []normalizedApplyAllSourceRevisionAdvance{advance},
		targets: map[string]*packs.SourceBackedPack{
			"crm": testApplyAllSourceRevisionTarget(t, "crm", "1.0.0", "official_repo", "crm", advance.ToRevision),
		},
	}
	tests := []struct {
		name   string
		runner *Runner
	}{
		{name: "nil runner"},
		{name: "nil connection", runner: &Runner{}},
		{name: "nil SQL database", runner: &Runner{DB: database.NewConnectionFromDB(nil)}},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			_, err := resolveApplyAllSourceRevisionAdvanceInstalledTuple(
				context.Background(), test.runner, precondition,
				testApplyAllSourceRevisionAdvanceSourceTuple(sourceTuple),
			)
			composeErr := assertApplyAllSourceRevisionComposeError(t, err, -1, "")
			if !strings.Contains(composeErr.Error(), "database connection is unavailable") {
				t.Fatalf("compose error = %v, want unavailable database", composeErr)
			}
		})
	}
}

func TestApplyAllSourceRevisionAdvanceActiveRuntimeObservationRequiresExactRunnerDatabase(t *testing.T) {
	dbA, mockA, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock A: %v", err)
	}
	t.Cleanup(func() { _ = dbA.Close() })
	expectApplyAllSourceRevisionAdvanceActiveRuntimeObservation(mockA)
	observation, err := readApplyAllSourceRevisionAdvanceActiveRuntimeObservation(context.Background(), dbA)
	if err != nil {
		t.Fatalf("read active runtime observation: %v", err)
	}
	if got, err := observation.databaseForRunner(&Runner{DB: database.NewConnectionFromDB(dbA)}); err != nil || got != dbA {
		t.Fatalf("matching runner database = %p, %v, want %p", got, err, dbA)
	}
	expectApplyAllSourceRevisionAdvanceActiveRuntimeObservation(mockA)
	secondObservation, err := readApplyAllSourceRevisionAdvanceActiveRuntimeObservation(context.Background(), dbA)
	if err != nil {
		t.Fatalf("read second active runtime observation: %v", err)
	}
	if observation.identity == nil || secondObservation.identity == nil || observation.identity == secondObservation.identity {
		t.Fatalf("observation identities = %p/%p, want distinct non-nil tokens", observation.identity, secondObservation.identity)
	}

	dbB, _, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock B: %v", err)
	}
	t.Cleanup(func() { _ = dbB.Close() })
	if _, err := observation.databaseForRunner(&Runner{DB: database.NewConnectionFromDB(dbB)}); err == nil || !strings.Contains(err.Error(), "different runner database") {
		t.Fatalf("mismatched runner error = %v, want fail closed", err)
	}
	if _, err := (applyAllSourceRevisionAdvanceActiveRuntimeObservation{}).databaseForRunner(&Runner{DB: database.NewConnectionFromDB(dbA)}); err == nil || !strings.Contains(err.Error(), "not minted") {
		t.Fatalf("unminted observation error = %v, want fail closed", err)
	}
	if _, err := (&applyAllSourceRevisionAdvanceActiveRuntimeIdentity{db: dbA}).requireDatabase(dbA); err == nil || !strings.Contains(err.Error(), "not minted") {
		t.Fatalf("snapshotless identity error = %v, want fail closed", err)
	}
	if err := mockA.ExpectationsWereMet(); err != nil {
		t.Fatalf("SQL expectations: %v", err)
	}
}

func TestResolveApplyAllSourceRevisionFormulaContextConsumesFrozenActivePeer(t *testing.T) {
	const (
		peerName     = "active-formula-peer"
		functionName = "ACTIVE_PEER_SENTINEL"
	)
	sourceDir := writeFormulaFunctionProviderPackSourceWithFunctionName(t, peerName, functionName)
	peer, err := packs.ResolveInstalledSourceBackedPack(
		peerName, packs.AppPack, string(packs.PackSourceKindLocalPath), sourceDir,
	)
	if err != nil {
		t.Fatalf("resolve active peer: %v", err)
	}
	payloadHash, err := packs.PackPayloadHash(peer)
	if err != nil {
		t.Fatalf("active peer payload hash: %v", err)
	}
	declaration, err := packs.BuildPersistedRuntimeDeclaration(peer)
	if err != nil {
		t.Fatalf("active peer persisted runtime declaration: %v", err)
	}

	rawDB, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock: %v", err)
	}
	t.Cleanup(func() { _ = rawDB.Close() })
	expectApplyAllSourceRevisionAdvanceActiveRuntimeObservationWithPeer(
		mock,
		peerName,
		sourceDir,
		payloadHash,
		declaration.ObjectPayloadsJSON(),
		declaration.RelatedListRulesJSON(),
		declaration.SearchScopeOrderJSON(),
		declaration.SearchAllDefaultFieldsJSON(),
		declaration.FormulaFunctionBundlesJSON(),
		declaration.StartupShallowDeclaredRowsJSON(),
	)
	observation, err := readApplyAllSourceRevisionAdvanceActiveRuntimeObservation(context.Background(), rawDB)
	if err != nil {
		t.Fatalf("read active runtime observation: %v", err)
	}
	bundles, err := resolveApplyAllSourceRevisionFormulaContext(
		context.Background(), observation.identity.snapshot, nil, packs.ComponentKindRegistrationSet{},
	)
	if err != nil {
		t.Fatalf("resolve formula context from frozen snapshot: %v", err)
	}
	var functionNames []string
	for _, bundle := range bundles {
		for _, function := range bundle.Functions {
			functionNames = append(functionNames, function.Name)
		}
	}
	if !reflect.DeepEqual(functionNames, []string{functionName}) {
		t.Fatalf("frozen active-peer functions = %v, want %s", functionNames, functionName)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("SQL expectations: %v", err)
	}
}

func TestResolveApplyAllSourceRevisionInstalledTargetFromFrozenContextRejectsLiveSchemaFallback(t *testing.T) {
	root := writeConnectorAssociationSchemaResolverPackSourceRoot(t)
	rawDB, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock: %v", err)
	}
	t.Cleanup(func() { _ = rawDB.Close() })
	sourceOptions := packs.DefaultPackSourceOptions()
	sourceOptions.ObjectSchemaResolver = testSourcePackSchemaResolver()
	_, err = resolveApplyAllSourceRevisionInstalledTargetFromFrozenContext(
		context.Background(),
		rawDB,
		installedPackRow{
			Name:                  "schema-resolver-app",
			Category:              string(packs.AppPack),
			ManifestFormatVersion: sql.NullString{Valid: true, String: packs.SupportedManifestFormatVersion},
			SourceKind:            sql.NullString{Valid: true, String: string(packs.PackSourceKindLocalPath)},
			SourceURI:             sql.NullString{Valid: true, String: root},
		},
		"",
		sourceOptions,
		nil,
		true,
		packs.ComponentKindRegistrationSet{},
	)
	if err == nil {
		t.Fatal("frozen-context resolver accepted a pack that requires mutable live schema")
	}
	if strings.Contains(err.Error(), "call to Query") {
		t.Fatalf("frozen-context resolver read live schema: %v", err)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("SQL expectations: %v", err)
	}
}

func TestResolveApplyAllSourceRevisionAdvanceInstalledTupleUsesOneExactTargetContext(t *testing.T) {
	const (
		providerName   = "installed-provider"
		consumerName   = "installed-consumer"
		providerFrom   = "provider-from"
		providerTarget = "provider-target"
		consumerFrom   = "consumer-from"
		consumerTarget = "consumer-target"
	)
	provider := testApplyAllSourceRevisionAdvance(providerName, 1)
	provider.FromRevision, provider.ToRevision = providerFrom, providerTarget
	consumer := testApplyAllSourceRevisionAdvance(consumerName, 0)
	consumer.FromRevision, consumer.ToRevision = consumerFrom, consumerTarget
	plan := []normalizedApplyAllSourceRevisionAdvance{consumer, provider}
	sourceTargets := map[string]*packs.SourceBackedPack{
		providerName: testApplyAllSourceRevisionTarget(t, providerName, "2.1.0", "official_repo", providerName, providerTarget),
		consumerName: testApplyAllSourceRevisionTarget(
			t, consumerName, "1.0.0", "official_repo", consumerName, consumerTarget,
			packs.PackDependency{Name: providerName, VersionConstraint: ">=2.0.0"},
		),
	}
	finalTargets := map[string]*packs.SourceBackedPack{
		providerName: testApplyAllSourceRevisionTarget(t, providerName, "2.1.0", "official_repo", providerName, providerTarget),
		consumerName: testApplyAllSourceRevisionTarget(
			t, consumerName, "1.0.0", "official_repo", consumerName, consumerTarget,
			packs.PackDependency{Name: providerName, VersionConstraint: ">=2.0.0"},
		),
	}
	sourceTuple := applyAllSourceRevisionAdvanceTuple{plan: plan, targets: sourceTargets}
	providerCurrent := testApplyAllSourceRevisionTarget(
		t, providerName, "2.0.0", provider.Kind, provider.URI, providerFrom,
	)
	consumerCurrent := testApplyAllSourceRevisionTarget(
		t, consumerName, "1.0.0", consumer.Kind, consumer.URI, consumerFrom,
	)
	providerProof := testApplyAllSourceRevisionAdvanceFrozenCurrentTargetProof(
		t, provider, providerCurrent, installedPackStatusActive, provider.Kind, testCurrentTargetV1Hash, nil,
	)
	consumerProof := testApplyAllSourceRevisionAdvanceFrozenCurrentTargetProof(
		t, consumer, consumerCurrent, installedPackStatusActive, consumer.Kind, testCurrentTargetV1Hash, nil,
	)
	precondition := applyAllSourceRevisionAdvancePreconditionProof{
		snapshot: applyAllSourceRevisionAdvanceCurrentSnapshot{entries: []applyAllSourceRevisionAdvanceCurrentSnapshotEntry{
			consumerProof.snapshot.entries[0], providerProof.snapshot.entries[0],
		}},
		current: applyAllSourceRevisionAdvanceTuple{
			plan: []normalizedApplyAllSourceRevisionAdvance{consumer, provider},
			targets: map[string]*packs.SourceBackedPack{
				consumerName: consumerCurrent,
				providerName: providerCurrent,
			},
		},
	}

	originalResolver := resolveApplyAllSourceRevisionInstalledTarget
	originalFormulaResolver := resolveApplyAllSourceRevisionFormulaContext
	t.Cleanup(func() {
		resolveApplyAllSourceRevisionInstalledTarget = originalResolver
		resolveApplyAllSourceRevisionFormulaContext = originalFormulaResolver
	})
	bundles := []formula.FunctionBundle{{Functions: []formula.FunctionDefinition{{Name: "installed-tuple-sentinel"}}}}

	rawDB, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock: %v", err)
	}
	t.Cleanup(func() { _ = rawDB.Close() })
	expectApplyAllSourceRevisionAdvanceActiveRuntimeObservation(mock)
	activeRuntime, err := readApplyAllSourceRevisionAdvanceActiveRuntimeObservation(context.Background(), rawDB)
	if err != nil {
		t.Fatalf("read active runtime observation: %v", err)
	}
	precondition.activeRuntime = activeRuntime
	formulaCalls := 0
	resolveApplyAllSourceRevisionFormulaContext = func(
		_ context.Context,
		snapshot *packs.ActiveInstalledRuntimeSnapshot,
		installing []packs.Pack,
		registrations packs.ComponentKindRegistrationSet,
	) ([]formula.FunctionBundle, error) {
		formulaCalls++
		assertApplyAllSourceRevisionRunnerTestRegistration(t, registrations)
		if snapshot == nil {
			t.Fatal("formula context snapshot = nil, want frozen active-runtime snapshot")
		}
		gotNames := make([]string, 0, len(installing))
		for _, pack := range installing {
			gotNames = append(gotNames, pack.Name())
		}
		if want := []string{providerName, consumerName}; !reflect.DeepEqual(gotNames, want) {
			t.Fatalf("formula installing order = %v, want dependency order %v", gotNames, want)
		}
		return bundles, nil
	}
	resolverCalls := 0
	resolveApplyAllSourceRevisionInstalledTarget = func(
		_ context.Context,
		gotDB *sql.DB,
		row installedPackRow,
		revision string,
		sourceOptions packs.PackSourceOptions,
		gotBundles []formula.FunctionBundle,
		hasBundles bool,
		registrations packs.ComponentKindRegistrationSet,
		opts ...packs.SourceBackedPackOption,
	) (*packs.SourceBackedPack, error) {
		resolverCalls++
		assertApplyAllSourceRevisionRunnerTestRegistration(t, registrations)
		wantFrom := map[string]string{providerName: providerFrom, consumerName: consumerFrom}[row.Name]
		wantTarget := map[string]string{providerName: providerTarget, consumerName: consumerTarget}[row.Name]
		if gotDB != rawDB || !row.SourceRevision.Valid || row.SourceRevision.String != wantFrom || revision != wantTarget {
			t.Fatalf("resolver %s DB/from/to = (%p, %#v, %q), want (%p, %q, %q)", row.Name, gotDB, row.SourceRevision, revision, rawDB, wantFrom, wantTarget)
		}
		wantRevisions := map[string]string{
			providerName: providerTarget,
			consumerName: consumerTarget,
		}
		if !reflect.DeepEqual(sourceOptions.OfficialRepoSourceRevisions, wantRevisions) {
			t.Fatalf("resolver %s source revisions = %#v, want complete target tuple %#v", row.Name, sourceOptions.OfficialRepoSourceRevisions, wantRevisions)
		}
		for _, fromRevision := range []string{providerFrom, consumerFrom} {
			for _, gotRevision := range sourceOptions.OfficialRepoSourceRevisions {
				if gotRevision == fromRevision {
					t.Fatalf("resolver %s source revisions retain from revision %q", row.Name, fromRevision)
				}
			}
		}
		if !hasBundles || !reflect.DeepEqual(gotBundles, bundles) {
			t.Fatalf("resolver %s formula context = (%#v, %t), want one authoritative tuple context", row.Name, gotBundles, hasBundles)
		}
		if len(opts) != 1 {
			t.Fatalf("resolver %s construction options = %d, want one frozen ownerless policy", row.Name, len(opts))
		}
		return finalTargets[row.Name], nil
	}

	registrations := runnerTestRegistrationSet(t)
	runner := &Runner{
		DB: database.NewConnectionFromDB(rawDB),
		SvcMgr: &runnerServiceGraph{options: RunnerOptions{
			ComponentKindRegistrationSet: registrations,
		}},
	}
	tuple, err := resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(), runner, precondition, testApplyAllSourceRevisionAdvanceSourceTuple(sourceTuple),
	)
	if err != nil {
		t.Fatalf("resolve installed target tuple: %v", err)
	}
	if formulaCalls != 1 || resolverCalls != 2 {
		t.Fatalf("formula/resolver calls = %d/%d, want 1/2", formulaCalls, resolverCalls)
	}
	if got := []string{tuple.plan[0].Name, tuple.plan[1].Name}; !reflect.DeepEqual(got, []string{providerName, consumerName}) {
		t.Fatalf("installed tuple order = %v, want provider before consumer", got)
	}
	if tuple.targets[providerName] != finalTargets[providerName] || tuple.targets[consumerName] != finalTargets[consumerName] {
		t.Fatalf("installed tuple targets = %#v, want resolver targets", tuple.targets)
	}
	if tuple.activeRuntimeIdentity == nil || tuple.activeRuntimeIdentity != precondition.activeRuntime.identity {
		t.Fatalf("installed tuple runtime identity = %p, want exact observation identity %p", tuple.activeRuntimeIdentity, precondition.activeRuntime.identity)
	}
	if !reflect.DeepEqual(sourceTuple.plan, plan) || sourceTuple.targets[providerName] != sourceTargets[providerName] || sourceTuple.targets[consumerName] != sourceTargets[consumerName] {
		t.Fatalf("source tuple was mutated: %#v", sourceTuple)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("SQL expectations: %v", err)
	}
}

func TestResolveApplyAllSourceRevisionAdvanceInstalledTupleFreezesDesiredOwnerlessPolicy(t *testing.T) {
	const packName = "ownerless-policy"
	advance := testApplyAllSourceRevisionAdvance(packName, 5)
	current, _ := testApplyAllSourceRevisionAdvanceObjectTarget(t, packName, advance.FromRevision, "Issue")
	desired, desiredSource := testApplyAllSourceRevisionAdvanceObjectTarget(t, packName, advance.ToRevision, "Issue", "Task")
	if got := desired.OwnedObjectAPINames(); !reflect.DeepEqual(got, []string{"Issue", "Task"}) {
		t.Fatalf("desired owned objects = %v, want Issue and Task", got)
	}
	precondition := testApplyAllSourceRevisionAdvanceFrozenCurrentTargetProof(
		t, advance, current, installedPackStatusActive, advance.Kind, testCurrentTargetV1Hash, nil,
	)

	rawDB, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock: %v", err)
	}
	t.Cleanup(func() { _ = rawDB.Close() })
	expectApplyAllSourceRevisionAdvanceActiveRuntimeObservation(mock)
	precondition.activeRuntime, err = readApplyAllSourceRevisionAdvanceActiveRuntimeObservation(
		context.Background(), rawDB,
	)
	if err != nil {
		t.Fatalf("read active runtime observation: %v", err)
	}

	originalResolver := resolveApplyAllSourceRevisionInstalledTarget
	t.Cleanup(func() { resolveApplyAllSourceRevisionInstalledTarget = originalResolver })
	var rebuilt *packs.SourceBackedPack
	resolveApplyAllSourceRevisionInstalledTarget = func(
		_ context.Context,
		gotDB *sql.DB,
		row installedPackRow,
		revision string,
		_ packs.PackSourceOptions,
		_ []formula.FunctionBundle,
		_ bool,
		_ packs.ComponentKindRegistrationSet,
		opts ...packs.SourceBackedPackOption,
	) (*packs.SourceBackedPack, error) {
		if gotDB != rawDB || row.Name != packName || row.SourceRevision.String != advance.FromRevision || revision != advance.ToRevision {
			t.Fatalf("resolver DB/row/revision = %p/%#v/%q, want frozen %p/%q/%q", gotDB, row, revision, rawDB, advance.FromRevision, advance.ToRevision)
		}
		if len(opts) != 1 {
			t.Fatalf("construction options = %d, want one frozen ownerless policy", len(opts))
		}
		var buildErr error
		rebuilt, buildErr = packs.NewSourceBackedPack(desiredSource, opts...)
		return rebuilt, buildErr
	}

	tuple, err := resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(),
		&Runner{DB: database.NewConnectionFromDB(rawDB)},
		precondition,
		testApplyAllSourceRevisionAdvanceSourceTuple(applyAllSourceRevisionAdvanceTuple{
			plan: []normalizedApplyAllSourceRevisionAdvance{advance},
			targets: map[string]*packs.SourceBackedPack{
				packName: desired,
			},
		}),
	)
	if err != nil {
		t.Fatalf("resolve installed target tuple: %v", err)
	}
	if tuple.targets[packName] != rebuilt {
		t.Fatalf("compatibility target = %p, want constructed %p", tuple.targets[packName], rebuilt)
	}
	components := rebuilt.Components()
	if len(components) != 1 {
		t.Fatalf("constructed components = %d, want one object spec", len(components))
	}
	component := reflect.ValueOf(components[0])
	if component.Kind() != reflect.Ptr {
		t.Fatalf("object component kind = %s, want pointer", component.Kind())
	}
	allowOwnerless := component.Elem().FieldByName("allowOwnerlessObjectAPI")
	if !allowOwnerless.IsValid() || allowOwnerless.Len() != 1 ||
		!allowOwnerless.MapIndex(reflect.ValueOf("issue")).IsValid() ||
		allowOwnerless.MapIndex(reflect.ValueOf("task")).IsValid() {
		t.Fatalf("constructed ownerless policy = %#v, want only frozen-current issue allowance", allowOwnerless)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("SQL expectations: %v", err)
	}
}

func TestResolveApplyAllSourceRevisionAdvanceInstalledTuplePreservesFinalTargetErrorIdentity(t *testing.T) {
	const packName = "wrong-installed-target"
	advance := testApplyAllSourceRevisionAdvance(packName, 7)
	currentTarget := testApplyAllSourceRevisionTarget(
		t, packName, "1.0.0", advance.Kind, advance.URI, advance.FromRevision,
	)
	precondition := testApplyAllSourceRevisionAdvanceFrozenCurrentTargetProof(
		t, advance, currentTarget, installedPackStatusActive, advance.Kind, testCurrentTargetV1Hash, nil,
	)
	sourceTuple := applyAllSourceRevisionAdvanceTuple{
		plan: []normalizedApplyAllSourceRevisionAdvance{advance},
		targets: map[string]*packs.SourceBackedPack{
			packName: testApplyAllSourceRevisionTarget(t, packName, "1.0.0", "official_repo", packName, advance.ToRevision),
		},
	}

	originalResolver := resolveApplyAllSourceRevisionInstalledTarget
	t.Cleanup(func() {
		resolveApplyAllSourceRevisionInstalledTarget = originalResolver
	})
	resolveApplyAllSourceRevisionInstalledTarget = func(
		context.Context, *sql.DB, installedPackRow, string, packs.PackSourceOptions, []formula.FunctionBundle, bool,
		packs.ComponentKindRegistrationSet, ...packs.SourceBackedPackOption,
	) (*packs.SourceBackedPack, error) {
		return testApplyAllSourceRevisionTarget(t, packName, "1.0.0", "official_repo", packName, "wrong"), nil
	}

	rawDB, mock, err := sqlmock.New()
	if err != nil {
		t.Fatalf("sqlmock: %v", err)
	}
	t.Cleanup(func() { _ = rawDB.Close() })
	expectApplyAllSourceRevisionAdvanceActiveRuntimeObservation(mock)
	activeRuntime, err := readApplyAllSourceRevisionAdvanceActiveRuntimeObservation(context.Background(), rawDB)
	if err != nil {
		t.Fatalf("read active runtime observation: %v", err)
	}
	precondition.activeRuntime = activeRuntime
	_, err = resolveApplyAllSourceRevisionAdvanceInstalledTuple(
		context.Background(), &Runner{DB: database.NewConnectionFromDB(rawDB)},
		precondition, testApplyAllSourceRevisionAdvanceSourceTuple(sourceTuple),
	)
	composeErr := assertApplyAllSourceRevisionComposeError(t, err, 7, packName)
	if !strings.Contains(composeErr.Error(), "identity/revision") {
		t.Fatalf("compose error = %v, want exact final target rejection", composeErr)
	}
	if err := mock.ExpectationsWereMet(); err != nil {
		t.Fatalf("SQL expectations: %v", err)
	}
}

func testApplyAllSourceRevisionAdvanceObjectTarget(
	t *testing.T,
	name string,
	revision string,
	objectAPINames ...string,
) (*packs.SourceBackedPack, *packs.ResolvedPackSource) {
	t.Helper()
	objectSpecs := make([]string, 0, len(objectAPINames))
	for _, objectAPIName := range objectAPINames {
		objectSpecs = append(objectSpecs, `{"apiName":"`+objectAPIName+`","label":"`+objectAPIName+`","tableType":"standard_object","category":"work","sharingModel":"Private","enableHierarchySharing":false,"fields":[{"apiName":"Subject","label":"Subject","type":"string","required":true,"isNameField":true}]}`)
	}
	source := &packs.ResolvedPackSource{
		Kind: string(packs.PackSourceKindOfficialRepo), URI: name, Revision: revision,
		Manifest: &packs.PackManifest{
			ManifestFormatVersion: packs.SupportedManifestFormatVersion,
			Name:                  name,
			DisplayName:           name,
			Category:              packs.AppPack,
			Version:               "1.0.0",
			PlatformCompatibility: packs.PlatformCompatibility{Min: "0.2.0", MaxExclusive: "0.3.0"},
			Components: []packs.ManifestComponent{{
				Kind:          packs.ComponentKindObjectSpec,
				BusinessKey:   "objects",
				Manageability: packs.ManageabilityLocked,
				Payload:       []byte(`[` + strings.Join(objectSpecs, ",") + `]`),
			}},
		},
		Files: map[string][]byte{}, FileRefs: []string{},
	}
	target, err := packs.NewSourceBackedPack(source)
	if err != nil {
		t.Fatalf("new source-backed object target: %v", err)
	}
	return target, source
}

func expectApplyAllSourceRevisionAdvanceActiveRuntimeObservation(mock sqlmock.Sqlmock) {
	mock.ExpectQuery("SELECT COLUMN_NAME\\s+FROM INFORMATION_SCHEMA\\.COLUMNS").
		WithArgs(
			"_System_InstalledPack",
			"RuntimeObjectSpecDeclarations",
			"RuntimeRelatedListRules",
			"RuntimeSearchScopeOrder",
			"RuntimeSearchAllDefaultFields",
		).
		WillReturnRows(sqlmock.NewRows([]string{"COLUMN_NAME"}))
	mock.ExpectQuery("SELECT Name, Category, AppliedPayloadHash, ManifestFormatVersion, SourceKind, SourceURI, SourceRevision\\s+FROM _System_InstalledPack").
		WillReturnRows(sqlmock.NewRows([]string{
			"Name", "Category", "AppliedPayloadHash", "ManifestFormatVersion", "SourceKind", "SourceURI", "SourceRevision",
		}))
}

func expectApplyAllSourceRevisionAdvanceActiveRuntimeObservationWithPeer(
	mock sqlmock.Sqlmock,
	name string,
	sourceURI string,
	payloadHash string,
	objectPayloads string,
	relatedListRules string,
	searchScopeOrder string,
	searchAllDefaultFields string,
	formulaFunctionBundles string,
	startupShallowDeclarations string,
) {
	mock.ExpectQuery("SELECT COLUMN_NAME\\s+FROM INFORMATION_SCHEMA\\.COLUMNS").
		WithArgs(
			"_System_InstalledPack",
			"RuntimeObjectSpecDeclarations",
			"RuntimeRelatedListRules",
			"RuntimeSearchScopeOrder",
			"RuntimeSearchAllDefaultFields",
		).
		WillReturnRows(sqlmock.NewRows([]string{"COLUMN_NAME"}).
			AddRow("RuntimeObjectSpecDeclarations").
			AddRow("RuntimeRelatedListRules").
			AddRow("RuntimeSearchScopeOrder").
			AddRow("RuntimeSearchAllDefaultFields"))
	mock.ExpectQuery("SELECT COUNT\\(\\*\\)\\s+FROM INFORMATION_SCHEMA\\.COLUMNS").
		WithArgs("_System_InstalledPack", "RuntimeStartupShallowDeclarations").
		WillReturnRows(sqlmock.NewRows([]string{"COUNT(*)"}).AddRow(1))
	mock.ExpectQuery("SELECT COUNT\\(\\*\\)\\s+FROM INFORMATION_SCHEMA\\.COLUMNS").
		WithArgs("_System_InstalledPack", "RuntimeFormulaFunctionBundles").
		WillReturnRows(sqlmock.NewRows([]string{"COUNT(*)"}).AddRow(1))
	mock.ExpectQuery("SELECT Name, Category, AppliedPayloadHash, ManifestFormatVersion, SourceKind, SourceURI, SourceRevision,\\s+RuntimeObjectSpecDeclarations, RuntimeRelatedListRules, RuntimeSearchScopeOrder, RuntimeSearchAllDefaultFields, RuntimeFormulaFunctionBundles, RuntimeStartupShallowDeclarations\\s+FROM _System_InstalledPack").
		WillReturnRows(sqlmock.NewRows([]string{
			"Name", "Category", "AppliedPayloadHash", "ManifestFormatVersion", "SourceKind", "SourceURI", "SourceRevision",
			"RuntimeObjectSpecDeclarations", "RuntimeRelatedListRules", "RuntimeSearchScopeOrder", "RuntimeSearchAllDefaultFields", "RuntimeFormulaFunctionBundles", "RuntimeStartupShallowDeclarations",
		}).AddRow(
			name,
			string(packs.AppPack),
			payloadHash,
			packs.SupportedManifestFormatVersion,
			string(packs.PackSourceKindLocalPath),
			sourceURI,
			nil,
			objectPayloads,
			relatedListRules,
			searchScopeOrder,
			searchAllDefaultFields,
			formulaFunctionBundles,
			startupShallowDeclarations,
		))
}

func assertApplyAllSourceRevisionRunnerTestRegistration(t *testing.T, set packs.ComponentKindRegistrationSet) {
	t.Helper()
	registrations := set.Registrations()
	if len(registrations) != 1 || string(registrations[0].Contract.Kind) != "runner_test" {
		t.Fatalf("registration set = %#v, want runner_test", registrations)
	}
}
