package catalogapp

import (
	"bytes"
	"context"
	"crypto/sha256"
	"database/sql"
	"encoding/hex"
	"errors"
	"fmt"
	"strings"
	"unicode"

	"github.com/pingcap-inc/nexuscrm-contract/pkg/appauthority"
	layoutbundlekeyv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/layoutbundlekeyv1"
	"github.com/pingcap-inc/nexuscrm-contract/pkg/layoutbundleslotv1"
	"github.com/pingcap-inc/nexuscrm-controlplane/releaseartifact"
)

// VerifyStoppedSourceReleaseCandidate performs the complete, storage-free
// package verification for an unsigned AppPackage supplied with caller-owned
// Git coordinates. It does not access Git or authenticate those coordinates.
// The returned reference binds them to the exact package bytes and to the
// non-promotable source receipt that Import persists.
func VerifyStoppedSourceReleaseCandidate(
	input StoppedSourceReleaseInput,
) (VerifiedStoppedSourceReleaseCandidate, StoppedSourceReleaseReference, error) {
	if err := appauthority.ValidateAppID(input.AppID); err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}
	if err := requireDigest("expected AppReleaseDigest", input.ExpectedAppReleaseDigest); err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}
	if err := requireDigest("expected package content digest", input.ExpectedPackageContentDigest); err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}

	_, parsed, err := releaseartifact.ParsePackage(input.PackageBytes)
	if err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}
	componentSet, err := verifyReleaseComponentSet(parsed.Package)
	if err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}
	verified := componentSet.packageFacts
	if verified.AppReleaseDigest != parsed.AppReleaseDigest ||
		!bytes.Equal(verified.CanonicalManifest, parsed.CanonicalManifest) ||
		!bytes.Equal(verified.CanonicalBundle, parsed.CanonicalBundle) {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, errors.New(
			"recognized component verification changed the stopped-source package carrier",
		)
	}
	if err := releaseartifact.VerifyCompatibility(verified, input.Compatibility); err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}
	for _, namespaceID := range verified.Manifest.OwnedNamespaces {
		if namespaceID == layoutbundlekeyv1.SystemSlotOwnerNamespace {
			return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, fmt.Errorf(
				"App release cannot own reserved system namespace %q",
				namespaceID,
			)
		}
	}

	packageContentDigest := exactPackageContentDigest(input.PackageBytes)
	if verified.Manifest.AppID != input.AppID ||
		verified.AppReleaseDigest != input.ExpectedAppReleaseDigest ||
		packageContentDigest != input.ExpectedPackageContentDigest {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, fmt.Errorf(
			"%w: stopped-source package does not match the caller's exact App and digest expectations",
			ErrConflict,
		)
	}
	reference, err := newStoppedSourceReleaseReference(
		input.AppID,
		verified.AppReleaseDigest,
		packageContentDigest,
		input.SourceRepository,
		input.SourceCommit,
	)
	if err != nil {
		return VerifiedStoppedSourceReleaseCandidate{}, StoppedSourceReleaseReference{}, err
	}
	return verifiedStoppedSourceReleaseCandidate(verified), reference, nil
}

func verifiedStoppedSourceReleaseCandidate(
	verified appauthority.VerifiedPackage,
) VerifiedStoppedSourceReleaseCandidate {
	return VerifiedStoppedSourceReleaseCandidate{
		AppID: verified.Manifest.AppID, PublisherID: verified.Manifest.PublisherID,
		SemanticVersion: verified.Manifest.SemanticVersion, AppReleaseDigest: verified.AppReleaseDigest,
		MetadataBundleDigest: verified.Manifest.MetadataBundleDigest, Package: verified,
	}
}

// ImportStoppedSourceRelease atomically persists one structurally verified,
// host-compatible AppRelease and its exact non-promotable caller-source
// receipt. It neither proves Git provenance, registers publisher trust, nor
// creates or changes global AppID ownership. The AppID must already be reserved
// to the package publisher.
func (a *Authority) ImportStoppedSourceRelease(
	ctx context.Context,
	input StoppedSourceReleaseInput,
) (RegisteredRelease, StoppedSourceReleaseReference, error) {
	candidate, reference, err := VerifyStoppedSourceReleaseCandidate(input)
	if err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}
	componentSet, err := verifyReleaseComponentSet(candidate.Package.Package)
	if err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}

	tx, err := a.db.BeginTx(ctx, nil)
	if err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}
	defer rollback(tx)
	if err := lockCatalogAppAdmissionFence(ctx, tx); err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}
	if err := lockStoppedSourceAppIdentity(ctx, tx, candidate); err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}

	replayed, err := replayStoppedSourceReleaseTx(ctx, tx, candidate, reference, componentSet.layoutBundleSlots)
	if err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}
	if !replayed {
		if err := insertStoppedSourceReleaseTx(ctx, tx, candidate.Package, reference, componentSet.layoutBundleSlots); err != nil {
			return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
		}
	}
	if err := tx.Commit(); err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}
	durable, err := a.ReadStoppedSourceRelease(ctx, reference)
	if err != nil {
		return RegisteredRelease{}, StoppedSourceReleaseReference{}, err
	}
	return durable, reference, nil
}

// ReadStoppedSourceRelease uses ReadRelease as the single stored-package read
// path, then proves that its canonical bytes are bound to the caller's exact
// non-promotable source receipt.
func (a *Authority) ReadStoppedSourceRelease(
	ctx context.Context,
	reference StoppedSourceReleaseReference,
) (RegisteredRelease, error) {
	release, err := a.ReadRelease(ctx, reference.AppID, reference.AppReleaseDigest)
	if err != nil {
		return RegisteredRelease{}, err
	}
	if release.AdmissionKind != ReleaseAdmissionStoppedSource {
		return RegisteredRelease{}, fmt.Errorf(
			"%w: AppRelease is not a stopped-source admission",
			ErrNotReady,
		)
	}
	expected, err := retainedSourceReleaseReceiptFromReference(reference)
	if err != nil {
		return RegisteredRelease{}, err
	}
	actual, err := a.readStoppedSourceReceipt(ctx, reference.AppID, reference.AppReleaseDigest)
	if err != nil {
		return RegisteredRelease{}, err
	}
	if err := validateRetainedSourceReleaseReceipt(actual); err != nil {
		return RegisteredRelease{}, err
	}
	if !sameStoppedSourceReceipt(actual, expected) {
		return RegisteredRelease{}, ErrConflict
	}
	packageBytes, err := packageBytesForVerifiedRelease(release.Package)
	if err != nil {
		return RegisteredRelease{}, fmt.Errorf("%w: rebuild stopped-source AppPackage: %v", ErrCorrupt, err)
	}
	if exactPackageContentDigest(packageBytes) != actual.packageContentDigest {
		return RegisteredRelease{}, fmt.Errorf(
			"%w: stopped-source receipt does not bind the stored AppPackage bytes",
			ErrCorrupt,
		)
	}
	if err := a.verifyStoppedSourceReleaseGraph(ctx, release); err != nil {
		return RegisteredRelease{}, err
	}
	return release, nil
}

// BeginStoppedSourceOperation is the only lifecycle entrypoint that accepts a
// non-promotable stopped-source release. It first proves the exact source
// reference, then reuses the ordinary Catalog operation transaction and
// lifecycle machinery. Version 1 intentionally rejects target dependencies;
// dependency admission needs its own exact stopped-source graph contract.
func (a *Authority) BeginStoppedSourceOperation(
	ctx context.Context,
	request BeginOperationRequest,
	reference StoppedSourceReleaseReference,
) (Operation, error) {
	if request.Kind == OperationRemove {
		return Operation{}, fmt.Errorf(
			"%w: stopped-source operation requires an exact target release",
			ErrInvalidTransition,
		)
	}
	if request.AppID != reference.AppID ||
		request.TargetAppReleaseDigest != reference.AppReleaseDigest {
		return Operation{}, ErrConflict
	}
	release, err := a.ReadStoppedSourceRelease(ctx, reference)
	if err != nil {
		return Operation{}, err
	}
	normalized, release, requestDigest, err := a.validateBeginOperationForTarget(
		ctx,
		request,
		&release,
		true,
	)
	if err != nil {
		return Operation{}, err
	}
	tx, err := a.db.BeginTx(ctx, nil)
	if err != nil {
		return Operation{}, err
	}
	defer rollback(tx)
	operation, err := a.beginOperationTx(
		ctx,
		tx,
		normalized,
		release,
		requestDigest,
		initiationDirect,
	)
	if err != nil {
		return Operation{}, err
	}
	if err := tx.Commit(); err != nil {
		return Operation{}, err
	}
	return operation, nil
}

func exactPackageContentDigest(packageBytes []byte) string {
	sum := sha256.Sum256(packageBytes)
	return "sha256:" + hex.EncodeToString(sum[:])
}

func newStoppedSourceReleaseReference(
	appID, appReleaseDigest, packageContentDigest, sourceRepository, sourceCommit string,
) (StoppedSourceReleaseReference, error) {
	receipt, err := canonicalStoppedSourceReceipt(
		appID,
		appReleaseDigest,
		packageContentDigest,
		sourceRepository,
		sourceCommit,
		"",
	)
	if err != nil {
		return StoppedSourceReleaseReference{}, err
	}
	return StoppedSourceReleaseReference{
		AppID: appID, AppReleaseDigest: appReleaseDigest,
		PackageContentDigest: packageContentDigest,
		SourceRepository:     sourceRepository,
		SourceCommit:         sourceCommit,
		ReceiptDigest:        receipt.receiptDigest,
	}, nil
}

func retainedSourceReleaseReceiptFromReference(
	reference StoppedSourceReleaseReference,
) (retainedSourceReleaseReceipt, error) {
	if err := requireDigest("stopped-source receipt digest", reference.ReceiptDigest); err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	return canonicalStoppedSourceReceipt(
		reference.AppID,
		reference.AppReleaseDigest,
		reference.PackageContentDigest,
		reference.SourceRepository,
		reference.SourceCommit,
		reference.ReceiptDigest,
	)
}

func canonicalStoppedSourceReceipt(
	appID, appReleaseDigest, packageContentDigest, sourceRepository, sourceCommit, receiptDigest string,
) (retainedSourceReleaseReceipt, error) {
	if err := appauthority.ValidateAppID(appID); err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	if err := requireDigest("stopped-source AppReleaseDigest", appReleaseDigest); err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	if err := requireDigest("stopped-source package content digest", packageContentDigest); err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	if strings.TrimSpace(sourceRepository) == "" ||
		sourceRepository != strings.TrimSpace(sourceRepository) ||
		len(sourceRepository) > 1024 ||
		strings.IndexFunc(sourceRepository, func(value rune) bool {
			return unicode.IsControl(value) || unicode.IsSpace(value)
		}) >= 0 {
		return retainedSourceReleaseReceipt{}, errors.New("stopped-source repository is not canonical")
	}
	if !lowercaseGitCommit.MatchString(sourceCommit) {
		return retainedSourceReleaseReceipt{}, errors.New(
			"stopped-source commit must be a lowercase 40-character Git object ID",
		)
	}
	receipt := retainedSourceReleaseReceipt{
		appID:                appID,
		appReleaseDigest:     appReleaseDigest,
		receiptSchema:        releaseSourceReceiptSchema,
		sourceRepository:     sourceRepository,
		sourceCommit:         sourceCommit,
		packageContentDigest: packageContentDigest,
		promotionDisposition: releaseSourceNonPromotable,
		releaseAdmissionKind: sql.NullString{String: string(ReleaseAdmissionStoppedSource), Valid: true},
	}
	expectedDigest, err := retainedSourceReleaseReceiptDigest(receipt)
	if err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	if receiptDigest != "" {
		if err := requireDigest("stopped-source receipt digest", receiptDigest); err != nil {
			return retainedSourceReleaseReceipt{}, err
		}
		if receiptDigest != expectedDigest {
			return retainedSourceReleaseReceipt{}, ErrConflict
		}
	}
	receipt.receiptDigest = expectedDigest
	return receipt, nil
}

func sameStoppedSourceReceipt(left, right retainedSourceReleaseReceipt) bool {
	return left.appID == right.appID &&
		left.appReleaseDigest == right.appReleaseDigest &&
		left.receiptSchema == right.receiptSchema &&
		left.sourceRepository == right.sourceRepository &&
		left.sourceCommit == right.sourceCommit &&
		left.packageContentDigest == right.packageContentDigest &&
		left.promotionDisposition == right.promotionDisposition &&
		left.receiptDigest == right.receiptDigest
}

func (a *Authority) readStoppedSourceReceipt(
	ctx context.Context,
	appID, appReleaseDigest string,
) (retainedSourceReleaseReceipt, error) {
	var receipt retainedSourceReleaseReceipt
	var rawAdmissionKind string
	var canonicalizationProfile, artifactMediaType string
	var attestationKeyID, attestationDigest sql.NullString
	var attestationVerifiedAt sql.NullTime
	var hasArtifactReceipt bool
	err := a.db.QueryRowContext(ctx, `SELECT s.ReceiptSchema, s.SourceRepository, s.SourceCommit,
s.PackageContentDigest, s.PromotionDisposition, s.ReceiptDigest,
r.CanonicalizationProfile, r.ArtifactMediaType, r.AdmissionKind,
r.AttestationKeyId, r.AttestationDigest, r.AttestationVerifiedAt,
(a.AppId IS NOT NULL) AS HasArtifactReceipt
FROM _System_CatalogAppRelease AS r
JOIN _System_CatalogAppReleaseSourceReceipt AS s
ON s.AppId = r.AppId AND s.AppReleaseDigest = r.AppReleaseDigest
LEFT JOIN _System_CatalogAppReleaseArtifactReceipt AS a
ON a.AppId = r.AppId AND a.AppReleaseDigest = r.AppReleaseDigest
WHERE r.AppId = ? AND r.AppReleaseDigest = ?`, appID, appReleaseDigest).Scan(
		&receipt.receiptSchema,
		&receipt.sourceRepository,
		&receipt.sourceCommit,
		&receipt.packageContentDigest,
		&receipt.promotionDisposition,
		&receipt.receiptDigest,
		&canonicalizationProfile,
		&artifactMediaType,
		&rawAdmissionKind,
		&attestationKeyID,
		&attestationDigest,
		&attestationVerifiedAt,
		&hasArtifactReceipt,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return retainedSourceReleaseReceipt{}, fmt.Errorf("%w: stopped-source receipt is absent", ErrCorrupt)
	}
	if err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	receipt.appID = appID
	receipt.appReleaseDigest = appReleaseDigest
	receipt.releaseAdmissionKind = sql.NullString{String: rawAdmissionKind, Valid: true}
	if canonicalizationProfile != releaseartifact.CanonicalizationProfile ||
		artifactMediaType != releaseartifact.ArtifactMediaType {
		return retainedSourceReleaseReceipt{}, fmt.Errorf(
			"%w: stopped-source AppRelease has invalid package carrier metadata",
			ErrCorrupt,
		)
	}
	if err := validateRetainedReleaseAdmission(retainedReleaseAdmission{
		appID:                 appID,
		appReleaseDigest:      appReleaseDigest,
		kind:                  ReleaseAdmissionKind(rawAdmissionKind),
		attestationKeyID:      attestationKeyID,
		attestationDigest:     attestationDigest,
		attestationVerifiedAt: attestationVerifiedAt,
		hasArtifactReceipt:    hasArtifactReceipt,
		hasSourceReceipt:      true,
	}); err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	return receipt, nil
}

func lockStoppedSourceAppIdentity(
	ctx context.Context,
	tx *sql.Tx,
	candidate VerifiedStoppedSourceReleaseCandidate,
) error {
	var publisherID string
	err := tx.QueryRowContext(ctx, `SELECT PublisherId
FROM _System_CatalogAppIdentity
WHERE AppId = ? FOR UPDATE`, candidate.AppID).Scan(&publisherID)
	if errors.Is(err, sql.ErrNoRows) {
		return fmt.Errorf(
			"%w: stopped-source import requires an existing AppIdentity",
			ErrNotReady,
		)
	}
	if err != nil {
		return err
	}
	if publisherID != candidate.PublisherID {
		return fmt.Errorf(
			"%w: stopped-source AppIdentity publisher does not match the package",
			ErrConflict,
		)
	}
	return nil
}

func replayStoppedSourceReleaseTx(
	ctx context.Context,
	tx *sql.Tx,
	candidate VerifiedStoppedSourceReleaseCandidate,
	reference StoppedSourceReleaseReference,
	slotDeclarations []layoutbundleslotv1.Declaration,
) (bool, error) {
	var existingDigest, existingPublisher, existingMetadataDigest string
	var existingProfile, existingMediaType, rawAdmissionKind string
	var existingKey, existingAttestation sql.NullString
	var existingVerifiedAt sql.NullTime
	var hasArtifactReceipt, hasSourceReceipt bool
	err := tx.QueryRowContext(ctx, `SELECT r.AppReleaseDigest, r.PublisherId, r.MetadataBundleDigest,
r.CanonicalizationProfile, r.ArtifactMediaType,
r.AdmissionKind, r.AttestationKeyId, r.AttestationDigest, r.AttestationVerifiedAt,
(a.AppId IS NOT NULL) AS HasArtifactReceipt, (s.AppId IS NOT NULL) AS HasSourceReceipt
FROM _System_CatalogAppRelease AS r
LEFT JOIN _System_CatalogAppReleaseArtifactReceipt AS a
ON a.AppId = r.AppId AND a.AppReleaseDigest = r.AppReleaseDigest
LEFT JOIN _System_CatalogAppReleaseSourceReceipt AS s
ON s.AppId = r.AppId AND s.AppReleaseDigest = r.AppReleaseDigest
WHERE r.AppId = ? AND r.SemanticVersion = ? FOR UPDATE`, candidate.AppID, candidate.SemanticVersion).Scan(
		&existingDigest,
		&existingPublisher,
		&existingMetadataDigest,
		&existingProfile,
		&existingMediaType,
		&rawAdmissionKind,
		&existingKey,
		&existingAttestation,
		&existingVerifiedAt,
		&hasArtifactReceipt,
		&hasSourceReceipt,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return false, nil
	}
	if err != nil {
		return false, err
	}
	admission := retainedReleaseAdmission{
		appID: candidate.AppID, appReleaseDigest: existingDigest,
		kind:                  ReleaseAdmissionKind(rawAdmissionKind),
		attestationKeyID:      existingKey,
		attestationDigest:     existingAttestation,
		attestationVerifiedAt: existingVerifiedAt,
		hasArtifactReceipt:    hasArtifactReceipt,
		hasSourceReceipt:      hasSourceReceipt,
	}
	if err := validateRetainedReleaseAdmission(admission); err != nil {
		return false, err
	}
	verified := candidate.Package
	if admission.kind != ReleaseAdmissionStoppedSource ||
		existingDigest != verified.AppReleaseDigest ||
		existingPublisher != verified.Manifest.PublisherID ||
		existingMetadataDigest != verified.Manifest.MetadataBundleDigest ||
		existingProfile != releaseartifact.CanonicalizationProfile ||
		existingMediaType != releaseartifact.ArtifactMediaType {
		return false, ErrConflict
	}
	expected, err := retainedSourceReleaseReceiptFromReference(reference)
	if err != nil {
		return false, err
	}
	actual, err := readStoppedSourceReceiptTx(ctx, tx, reference.AppID, reference.AppReleaseDigest)
	if err != nil {
		return false, err
	}
	if err := validateRetainedSourceReleaseReceipt(actual); err != nil {
		return false, err
	}
	if !sameStoppedSourceReceipt(actual, expected) {
		return false, ErrConflict
	}
	if err := verifyReleaseLayoutBundleSlotsTx(
		ctx,
		tx,
		reference.AppID,
		reference.AppReleaseDigest,
		slotDeclarations,
	); err != nil {
		return false, err
	}
	return true, nil
}

func readStoppedSourceReceiptTx(
	ctx context.Context,
	tx *sql.Tx,
	appID, appReleaseDigest string,
) (retainedSourceReleaseReceipt, error) {
	var receipt retainedSourceReleaseReceipt
	err := tx.QueryRowContext(ctx, `SELECT ReceiptSchema, SourceRepository, SourceCommit,
PackageContentDigest, PromotionDisposition, ReceiptDigest
FROM _System_CatalogAppReleaseSourceReceipt
WHERE AppId = ? AND AppReleaseDigest = ? FOR UPDATE`, appID, appReleaseDigest).Scan(
		&receipt.receiptSchema,
		&receipt.sourceRepository,
		&receipt.sourceCommit,
		&receipt.packageContentDigest,
		&receipt.promotionDisposition,
		&receipt.receiptDigest,
	)
	if errors.Is(err, sql.ErrNoRows) {
		return retainedSourceReleaseReceipt{}, fmt.Errorf("%w: stopped-source receipt is absent", ErrCorrupt)
	}
	if err != nil {
		return retainedSourceReleaseReceipt{}, err
	}
	receipt.appID = appID
	receipt.appReleaseDigest = appReleaseDigest
	receipt.releaseAdmissionKind = sql.NullString{String: string(ReleaseAdmissionStoppedSource), Valid: true}
	return receipt, nil
}

func insertStoppedSourceReleaseTx(
	ctx context.Context,
	tx *sql.Tx,
	verified appauthority.VerifiedPackage,
	reference StoppedSourceReleaseReference,
	slotDeclarations []layoutbundleslotv1.Declaration,
) error {
	manifest := verified.Manifest
	if _, err := tx.ExecContext(ctx, `INSERT INTO _System_CatalogAppRelease
(AppId, AppReleaseDigest, PublisherId, SemanticVersion, MetadataBundleDigest, CanonicalManifest, CanonicalBundle,
CanonicalizationProfile, ArtifactMediaType, AdmissionKind, AttestationKeyId, AttestationDigest, AttestationVerifiedAt, CreatedDate)
VALUES (?, ?, ?, ?, ?, CAST(? AS JSON), CAST(? AS JSON), ?, ?, ?, NULL, NULL, NULL, CURRENT_TIMESTAMP(6))`,
		manifest.AppID,
		verified.AppReleaseDigest,
		manifest.PublisherID,
		manifest.SemanticVersion,
		manifest.MetadataBundleDigest,
		verified.CanonicalManifest,
		verified.CanonicalBundle,
		releaseartifact.CanonicalizationProfile,
		releaseartifact.ArtifactMediaType,
		ReleaseAdmissionStoppedSource,
	); err != nil {
		if isDuplicate(err) {
			return ErrConflict
		}
		return err
	}
	if err := insertStoppedSourceReceiptTx(ctx, tx, reference); err != nil {
		return err
	}
	return insertReleaseGraphTx(ctx, tx, verified, slotDeclarations)
}

func insertStoppedSourceReceiptTx(
	ctx context.Context,
	tx *sql.Tx,
	reference StoppedSourceReleaseReference,
) error {
	receipt, err := retainedSourceReleaseReceiptFromReference(reference)
	if err != nil {
		return err
	}
	if _, err := tx.ExecContext(ctx, `INSERT INTO _System_CatalogAppReleaseSourceReceipt
(AppId, AppReleaseDigest, ReceiptSchema, SourceRepository, SourceCommit, PackageContentDigest,
PromotionDisposition, ReceiptDigest, CreatedDate)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP(6))`,
		receipt.appID,
		receipt.appReleaseDigest,
		receipt.receiptSchema,
		receipt.sourceRepository,
		receipt.sourceCommit,
		receipt.packageContentDigest,
		receipt.promotionDisposition,
		receipt.receiptDigest,
	); err != nil {
		if isDuplicate(err) {
			return ErrConflict
		}
		return err
	}
	return nil
}
