package catalogapp

import (
	"context"
	"database/sql"
	"errors"
	"fmt"
	"sort"
	"strings"
	"time"

	"github.com/pingcap-inc/nexuscrm-contract/pkg/appauthority"
	layoutbundlekeyv1 "github.com/pingcap-inc/nexuscrm-contract/pkg/layoutbundlekeyv1"
	"github.com/pingcap-inc/nexuscrm-controlplane/internal/catalogadmissionfence"
)

func lockCatalogAppAdmissionFence(ctx context.Context, tx *sql.Tx) error {
	if _, err := catalogadmissionfence.LockExclusive(ctx, tx); err != nil {
		return fmt.Errorf(
			"%w: publication admission fence: %v",
			ErrCorrupt,
			err,
		)
	}
	return nil
}

func (a *Authority) RegisterPublisher(ctx context.Context, trust PublisherTrust, expectedEpoch uint64) (uint64, error) {
	trust, err := canonicalPublisherTrust(trust)
	if err != nil {
		return 0, err
	}
	tx, err := a.db.BeginTx(ctx, nil)
	if err != nil {
		return 0, err
	}
	defer rollback(tx)
	newEpoch, err := applyPublisherTrustTx(ctx, tx, trust, expectedEpoch)
	if err != nil {
		return 0, err
	}
	if err := tx.Commit(); err != nil {
		return 0, err
	}
	return newEpoch, nil
}

func applyPublisherTrustTx(
	ctx context.Context, tx *sql.Tx, trust PublisherTrust, expectedEpoch uint64,
) (uint64, error) {
	keys := trust.Keys
	newEpoch := expectedEpoch + 1
	if newEpoch == 0 {
		return 0, fmt.Errorf("publisher ownership epoch exhausted")
	}
	state := "REVOKED"
	if trust.Active {
		state = "ACTIVE"
	}
	var err error
	if expectedEpoch == 0 {
		_, err = tx.ExecContext(ctx, `INSERT INTO _System_CatalogPublisher
(PublisherId, OwnershipEpoch, State, CreatedDate, LastModifiedDate)
VALUES (?, ?, ?, CURRENT_TIMESTAMP(6), CURRENT_TIMESTAMP(6))`, trust.PublisherID, epochText(newEpoch), state)
		if isDuplicate(err) {
			return 0, ErrConflict
		}
	} else {
		var result sql.Result
		result, err = tx.ExecContext(ctx, `UPDATE _System_CatalogPublisher
SET OwnershipEpoch = ?, State = ?, LastModifiedDate = CURRENT_TIMESTAMP(6)
WHERE PublisherId = ? AND OwnershipEpoch = ?`, epochText(newEpoch), state, trust.PublisherID, epochText(expectedEpoch))
		if err == nil {
			var affected int64
			affected, err = result.RowsAffected()
			if err == nil && affected != 1 {
				return 0, ErrConflict
			}
		}
	}
	if err != nil {
		return 0, err
	}
	if _, err := tx.ExecContext(ctx, `UPDATE _System_CatalogPublisherKey SET State = 'REVOKED', LastModifiedDate = CURRENT_TIMESTAMP(6)
WHERE PublisherId = ? AND State = 'ACTIVE'`, trust.PublisherID); err != nil {
		return 0, err
	}
	for _, key := range keys {
		_, insertErr := tx.ExecContext(ctx, `INSERT INTO _System_CatalogPublisherKey
(PublisherId, KeyId, Algorithm, PublicKey, ValidFrom, ValidUntil, State, CreatedDate, LastModifiedDate)
VALUES (?, ?, ?, ?, ?, ?, 'ACTIVE', CURRENT_TIMESTAMP(6), CURRENT_TIMESTAMP(6))`, trust.PublisherID, key.KeyID, key.Algorithm, key.PublicKey, key.ValidFrom.UTC(), key.ValidUntil.UTC())
		if isDuplicate(insertErr) {
			result, updateErr := tx.ExecContext(ctx, `UPDATE _System_CatalogPublisherKey SET State = 'ACTIVE', LastModifiedDate = CURRENT_TIMESTAMP(6)
WHERE PublisherId = ? AND KeyId = ? AND Algorithm = ? AND PublicKey = ? AND ValidFrom = ? AND ValidUntil = ?`,
				trust.PublisherID, key.KeyID, key.Algorithm, key.PublicKey, key.ValidFrom.UTC(), key.ValidUntil.UTC())
			if updateErr != nil {
				return 0, updateErr
			}
			affected, updateErr := result.RowsAffected()
			if updateErr != nil || affected != 1 {
				return 0, ErrConflict
			}
			continue
		}
		if insertErr != nil {
			return 0, insertErr
		}
	}
	return newEpoch, nil
}

func canonicalPublisherTrust(trust PublisherTrust) (PublisherTrust, error) {
	if err := appauthority.ValidatePublisherID(trust.PublisherID); err != nil {
		return PublisherTrust{}, err
	}
	if len(trust.Keys) == 0 && trust.Active {
		return PublisherTrust{}, fmt.Errorf("active publisher requires at least one key")
	}
	keys := append([]PublisherKey(nil), trust.Keys...)
	sort.Slice(keys, func(i, j int) bool { return keys[i].KeyID < keys[j].KeyID })
	for i, key := range keys {
		if strings.TrimSpace(key.KeyID) == "" || len(key.KeyID) > 128 || strings.TrimSpace(key.Algorithm) == "" || len(key.PublicKey) == 0 || key.ValidFrom.IsZero() || !key.ValidUntil.After(key.ValidFrom) {
			return PublisherTrust{}, fmt.Errorf("publisher key[%d] is incomplete", i)
		}
		if i > 0 && key.KeyID == keys[i-1].KeyID {
			return PublisherTrust{}, fmt.Errorf("publisher keys contain duplicate KeyID %q", key.KeyID)
		}
		keys[i].PublicKey = append([]byte(nil), key.PublicKey...)
		keys[i].ValidFrom = key.ValidFrom.UTC().Truncate(time.Microsecond)
		keys[i].ValidUntil = key.ValidUntil.UTC().Truncate(time.Microsecond)
	}
	trust.Keys = keys
	return trust, nil
}

func (a *Authority) ReserveAppID(ctx context.Context, publisherID, appID string, expectedPublisherEpoch uint64) error {
	if err := appauthority.ValidatePublisherID(publisherID); err != nil {
		return err
	}
	if err := appauthority.ValidateAppID(appID); err != nil {
		return err
	}
	if appID == layoutbundlekeyv1.SystemSlotOwnerNamespace {
		return fmt.Errorf("%w: system namespace cannot be reserved as an AppID", ErrConflict)
	}
	tx, err := a.db.BeginTx(ctx, nil)
	if err != nil {
		return err
	}
	defer rollback(tx)
	if _, err := catalogadmissionfence.LockExclusive(ctx, tx); err != nil {
		return fmt.Errorf("%w: publication admission fence: %v", ErrCorrupt, err)
	}
	var rawEpoch []byte
	var state string
	if err := tx.QueryRowContext(ctx, `SELECT OwnershipEpoch, State FROM _System_CatalogPublisher WHERE PublisherId = ? FOR UPDATE`, publisherID).Scan(&rawEpoch, &state); err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return ErrNotFound
		}
		return err
	}
	epoch, err := parseEpoch(rawEpoch)
	if err != nil {
		return err
	}
	if state != "ACTIVE" || epoch != expectedPublisherEpoch {
		return ErrConflict
	}
	_, err = tx.ExecContext(ctx, `INSERT INTO _System_CatalogAppIdentity
(AppId, PublisherId, OwnershipEpoch, CreatedDate, LastModifiedDate)
VALUES (?, ?, 1, CURRENT_TIMESTAMP(6), CURRENT_TIMESTAMP(6))`, appID, publisherID)
	if isDuplicate(err) {
		var existingPublisher string
		if queryErr := tx.QueryRowContext(ctx, `SELECT PublisherId FROM _System_CatalogAppIdentity WHERE AppId = ? FOR UPDATE`, appID).Scan(&existingPublisher); queryErr != nil {
			return queryErr
		}
		if existingPublisher != publisherID {
			return ErrConflict
		}
		err = nil
	}
	if err != nil {
		return err
	}
	return tx.Commit()
}

func (a *Authority) TransferAppID(ctx context.Context, transfer AppIDTransfer) (uint64, error) {
	if err := appauthority.ValidateAppID(transfer.AppID); err != nil {
		return 0, err
	}
	if err := appauthority.ValidatePublisherID(transfer.CurrentPublisherID); err != nil {
		return 0, err
	}
	if err := appauthority.ValidatePublisherID(transfer.NewPublisherID); err != nil {
		return 0, err
	}
	if !transfer.CurrentPublisherApproved || !transfer.OperatorApproved || transfer.CurrentPublisherID == transfer.NewPublisherID {
		return 0, ErrConflict
	}
	if err := requireDigest("transfer audit digest", transfer.AuditDigest); err != nil {
		return 0, err
	}
	tx, err := a.db.BeginTx(ctx, nil)
	if err != nil {
		return 0, err
	}
	defer rollback(tx)
	var currentPublisher string
	var rawEpoch []byte
	if err := tx.QueryRowContext(ctx, `SELECT PublisherId, OwnershipEpoch FROM _System_CatalogAppIdentity WHERE AppId = ? FOR UPDATE`, transfer.AppID).Scan(&currentPublisher, &rawEpoch); err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return 0, ErrNotFound
		}
		return 0, err
	}
	epoch, err := parseEpoch(rawEpoch)
	if err != nil {
		return 0, err
	}
	if currentPublisher != transfer.CurrentPublisherID || epoch != transfer.ExpectedOwnershipEpoch {
		return 0, ErrConflict
	}
	var newPublisherState string
	if err := tx.QueryRowContext(ctx, `SELECT State FROM _System_CatalogPublisher WHERE PublisherId = ? FOR UPDATE`, transfer.NewPublisherID).Scan(&newPublisherState); err != nil {
		return 0, ErrNotFound
	}
	if newPublisherState != "ACTIVE" {
		return 0, ErrConflict
	}
	newEpoch := epoch + 1
	result, err := tx.ExecContext(ctx, `UPDATE _System_CatalogAppIdentity
SET PublisherId = ?, OwnershipEpoch = ?, LastModifiedDate = CURRENT_TIMESTAMP(6)
WHERE AppId = ? AND PublisherId = ? AND OwnershipEpoch = ?`, transfer.NewPublisherID, epochText(newEpoch), transfer.AppID, transfer.CurrentPublisherID, epochText(epoch))
	if err != nil {
		return 0, err
	}
	affected, err := result.RowsAffected()
	if err != nil || affected != 1 {
		return 0, ErrConflict
	}
	auditID, err := a.newID(a.now())
	if err != nil {
		return 0, err
	}
	if _, err := tx.ExecContext(ctx, `INSERT INTO _System_CatalogAppTransferAudit
(Id, AppId, OldPublisherId, NewPublisherId, OwnershipEpoch, AuditDigest, CreatedDate)
VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP(6))`, auditID, transfer.AppID, transfer.CurrentPublisherID, transfer.NewPublisherID, epochText(newEpoch), transfer.AuditDigest); err != nil {
		return 0, err
	}
	if err := tx.Commit(); err != nil {
		return 0, err
	}
	return newEpoch, nil
}

// registerVerifiedRelease persists a release only after ImportReleaseArtifact
// has verified its detached publisher attestation. It is intentionally private:
// a caller must never be able to register an asserted verified package or
// attestation.
func (a *Authority) registerVerifiedRelease(ctx context.Context, registration verifiedReleaseRegistration) (RegisteredRelease, error) {
	supplied := registration.artifact.Package
	attestation := registration.artifact.Attestation
	verifiedAt := registration.verifiedAt.UTC().Truncate(time.Microsecond)
	receipt, err := newReleaseArtifactReceipt(registration)
	if err != nil {
		// registerVerifiedRelease is the collision boundary for the private
		// importer carrier. A carrier that disagrees with its retained signed
		// bytes is a conflict, including when an internal caller constructs it
		// inconsistently before the existing-release lookup.
		return RegisteredRelease{}, fmt.Errorf("%w: invalid verified release artifact receipt: %v", ErrConflict, err)
	}
	componentSet, err := verifyReleaseComponentSet(supplied.Package)
	if err != nil {
		return RegisteredRelease{}, err
	}
	verified := componentSet.packageFacts
	slotDeclarations := componentSet.layoutBundleSlots
	if supplied.AppReleaseDigest != verified.AppReleaseDigest || string(supplied.CanonicalManifest) != string(verified.CanonicalManifest) || string(supplied.CanonicalBundle) != string(verified.CanonicalBundle) {
		return RegisteredRelease{}, fmt.Errorf("verified package carrier does not match canonical package")
	}
	manifest := verified.Manifest
	for _, namespaceID := range manifest.OwnedNamespaces {
		if namespaceID == layoutbundlekeyv1.SystemSlotOwnerNamespace {
			return RegisteredRelease{}, fmt.Errorf(
				"App release cannot own reserved system namespace %q",
				namespaceID,
			)
		}
	}
	if attestation.PublisherID != manifest.PublisherID || attestation.AppID != manifest.AppID || attestation.SemanticVersion != manifest.SemanticVersion || attestation.AppReleaseDigest != verified.AppReleaseDigest || attestation.IssuedAt.IsZero() || verifiedAt.IsZero() {
		return RegisteredRelease{}, fmt.Errorf("publisher attestation does not bind the complete release tuple")
	}
	if strings.TrimSpace(attestation.CanonicalizationProfile) == "" || len(attestation.CanonicalizationProfile) > 64 ||
		strings.TrimSpace(attestation.ArtifactMediaType) == "" || len(attestation.ArtifactMediaType) > 255 {
		return RegisteredRelease{}, fmt.Errorf("publisher attestation canonicalization profile and artifact media type are required")
	}
	if err := requireDigest("attestation digest", attestation.AttestationDigest); err != nil {
		return RegisteredRelease{}, err
	}
	tx, err := a.db.BeginTx(ctx, nil)
	if err != nil {
		return RegisteredRelease{}, err
	}
	defer rollback(tx)
	if _, err := catalogadmissionfence.LockExclusive(ctx, tx); err != nil {
		return RegisteredRelease{}, fmt.Errorf(
			"%w: publication admission fence: %v",
			ErrCorrupt,
			err,
		)
	}
	var reservedPublisher string
	if err := tx.QueryRowContext(ctx, `SELECT PublisherId FROM _System_CatalogAppIdentity WHERE AppId = ? FOR UPDATE`, manifest.AppID).Scan(&reservedPublisher); err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return RegisteredRelease{}, ErrNotFound
		}
		return RegisteredRelease{}, err
	}
	if reservedPublisher != manifest.PublisherID {
		return RegisteredRelease{}, ErrConflict
	}
	if err := a.lockReleaseSigningKey(ctx, tx, registration); err != nil {
		return RegisteredRelease{}, err
	}
	var existingDigest, existingPublisher, 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.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`, manifest.AppID, manifest.SemanticVersion).Scan(&existingDigest,
		&existingPublisher, &existingProfile, &existingMediaType, &rawAdmissionKind,
		&existingKey, &existingAttestation, &existingVerifiedAt, &hasArtifactReceipt, &hasSourceReceipt)
	if err == nil {
		admission := retainedReleaseAdmission{
			appID: manifest.AppID, appReleaseDigest: existingDigest,
			kind:             ReleaseAdmissionKind(rawAdmissionKind),
			attestationKeyID: existingKey, attestationDigest: existingAttestation,
			attestationVerifiedAt: existingVerifiedAt,
			hasArtifactReceipt:    hasArtifactReceipt,
			hasSourceReceipt:      hasSourceReceipt,
		}
		if validationErr := validateRetainedReleaseAdmission(admission); validationErr != nil {
			return RegisteredRelease{}, validationErr
		}
		if admission.kind != ReleaseAdmissionSignedPublisher {
			return RegisteredRelease{}, ErrConflict
		}
		if existingDigest != verified.AppReleaseDigest || existingPublisher != manifest.PublisherID ||
			existingProfile != attestation.CanonicalizationProfile || existingMediaType != attestation.ArtifactMediaType ||
			existingKey.String != attestation.KeyID || existingAttestation.String != attestation.AttestationDigest {
			return RegisteredRelease{}, ErrConflict
		}
		if err := verifyStoredReleaseArtifactReceiptTx(ctx, tx, manifest.AppID, verified.AppReleaseDigest, receipt); err != nil && !errors.Is(err, errReleaseArtifactReceiptAbsent) {
			return RegisteredRelease{}, err
		}
		// A legacy row has no receipt because it predates sealed import. Preserve
		// the exact immutable replay, but never attach a newly supplied receipt:
		// later source authority still fails closed for that release until an
		// explicit stopped-phase provenance disposition exists.
		if err := verifyReleaseLayoutBundleSlotsTx(ctx, tx, manifest.AppID, verified.AppReleaseDigest, slotDeclarations); err != nil {
			return RegisteredRelease{}, err
		}
		// VerifiedAt records the first successful verification of this exact
		// immutable attestation. A later verification of the same proof is a
		// replay, not a different release receipt; retaining the original time
		// makes lost-response and restart retries idempotent. A different proof
		// still conflicts through AttestationDigest above.
		if err := tx.Commit(); err != nil {
			return RegisteredRelease{}, err
		}
		return registeredRelease(verified), nil
	}
	if !errors.Is(err, sql.ErrNoRows) {
		return RegisteredRelease{}, err
	}
	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), ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP(6))`, manifest.AppID,
		verified.AppReleaseDigest, manifest.PublisherID, manifest.SemanticVersion, manifest.MetadataBundleDigest,
		verified.CanonicalManifest, verified.CanonicalBundle, attestation.CanonicalizationProfile,
		attestation.ArtifactMediaType, ReleaseAdmissionSignedPublisher, attestation.KeyID,
		attestation.AttestationDigest, verifiedAt); err != nil {
		if isDuplicate(err) {
			return RegisteredRelease{}, ErrConflict
		}
		return RegisteredRelease{}, err
	}
	if err := insertReleaseArtifactReceiptTx(ctx, tx, manifest.AppID, verified.AppReleaseDigest, receipt); err != nil {
		return RegisteredRelease{}, err
	}
	if err := insertReleaseGraphTx(ctx, tx, verified, slotDeclarations); err != nil {
		return RegisteredRelease{}, err
	}
	if err := tx.Commit(); err != nil {
		return RegisteredRelease{}, err
	}
	return registeredRelease(verified), nil
}

func (a *Authority) ReadRelease(ctx context.Context, appID, digest string) (RegisteredRelease, error) {
	if err := appauthority.ValidateAppID(appID); err != nil {
		return RegisteredRelease{}, err
	}
	if err := requireDigest("AppReleaseDigest", digest); err != nil {
		return RegisteredRelease{}, err
	}
	var publisherID, semanticVersion, metadataDigest, rawAdmissionKind string
	var manifestRaw, bundleRaw []byte
	if err := a.db.QueryRowContext(ctx, `SELECT PublisherId, SemanticVersion, MetadataBundleDigest, AdmissionKind, CanonicalManifest, CanonicalBundle
FROM _System_CatalogAppRelease WHERE AppId = ? AND AppReleaseDigest = ?`, appID, digest).Scan(
		&publisherID, &semanticVersion, &metadataDigest, &rawAdmissionKind, &manifestRaw, &bundleRaw,
	); err != nil {
		if errors.Is(err, sql.ErrNoRows) {
			return RegisteredRelease{}, ErrNotFound
		}
		return RegisteredRelease{}, err
	}
	manifest, err := appauthority.ParseAppManifest(manifestRaw)
	if err != nil {
		return RegisteredRelease{}, err
	}
	bundle, err := appauthority.ParseMetadataBundle(bundleRaw, manifest)
	if err != nil {
		return RegisteredRelease{}, err
	}
	rows, err := a.db.QueryContext(ctx, `SELECT ComponentId, CanonicalBehavior FROM _System_CatalogAppReleaseComponent
WHERE AppId = ? AND AppReleaseDigest = ? ORDER BY ComponentId`, appID, digest)
	if err != nil {
		return RegisteredRelease{}, err
	}
	defer rows.Close()
	blobs := make([]appauthority.ComponentBlob, 0, len(bundle.Components))
	for rows.Next() {
		var blob appauthority.ComponentBlob
		if err := rows.Scan(&blob.ComponentID, &blob.CanonicalBehavior); err != nil {
			return RegisteredRelease{}, err
		}
		blobs = append(blobs, blob)
	}
	if err := rows.Err(); err != nil {
		return RegisteredRelease{}, err
	}
	componentSet, err := verifyReleaseComponentSet(appauthority.Package{Manifest: manifest, Bundle: bundle, ComponentBlobs: blobs})
	if err != nil {
		return RegisteredRelease{}, err
	}
	verified := componentSet.packageFacts
	slotDeclarations := componentSet.layoutBundleSlots
	if err := validateStoredReleaseLookup(appID, digest, publisherID, semanticVersion, metadataDigest, manifest, verified); err != nil {
		return RegisteredRelease{}, err
	}
	bindings, err := a.ReadReleaseLayoutBundleSlots(ctx, appID, digest)
	if err != nil {
		return RegisteredRelease{}, err
	}
	if _, err := compareReleaseLayoutBundleSlotBindings(bindings, appID, digest, slotDeclarations); err != nil {
		return RegisteredRelease{}, err
	}
	admissionKind := ReleaseAdmissionKind(rawAdmissionKind)
	if admissionKind != ReleaseAdmissionSignedPublisher && admissionKind != ReleaseAdmissionStoppedSource {
		return RegisteredRelease{}, fmt.Errorf("%w: stored AppRelease has invalid AdmissionKind %q", ErrCorrupt, rawAdmissionKind)
	}
	return registeredReleaseWithAdmission(verified, admissionKind), nil
}

func validateStoredReleaseLookup(appID, digest, publisherID, semanticVersion, metadataDigest string, manifest appauthority.AppManifest, verified appauthority.VerifiedPackage) error {
	if manifest.AppID != appID || verified.AppReleaseDigest != digest ||
		publisherID != manifest.PublisherID || semanticVersion != manifest.SemanticVersion ||
		metadataDigest != manifest.MetadataBundleDigest {
		return fmt.Errorf("%w: stored release facts disagree with its lookup", ErrCorrupt)
	}
	return nil
}

func registeredRelease(verified appauthority.VerifiedPackage) RegisteredRelease {
	return registeredReleaseWithAdmission(verified, ReleaseAdmissionSignedPublisher)
}

func registeredReleaseWithAdmission(
	verified appauthority.VerifiedPackage,
	admissionKind ReleaseAdmissionKind,
) RegisteredRelease {
	return RegisteredRelease{
		AppID: verified.Manifest.AppID, PublisherID: verified.Manifest.PublisherID,
		SemanticVersion: verified.Manifest.SemanticVersion, AppReleaseDigest: verified.AppReleaseDigest,
		MetadataBundleDigest: verified.Manifest.MetadataBundleDigest,
		AdmissionKind:        admissionKind,
		Package:              verified,
	}
}

func attestationWithin(now time.Time, key PublisherKey) bool {
	return !now.Before(key.ValidFrom) && now.Before(key.ValidUntil)
}
