export type Sha256Digest = `sha256:${string}`;
export type PluginPackageUpdatePolicy =
  | 'same-major'
  | 'same-minor'
  | 'any-forward'
  | 'manual';

export interface SignedPluginPackageMetadataV1 {
  readonly schemaVersion: 1;
  readonly trustStore: 'thortiq-plugin-publisher-v1';
  readonly publisherId: string;
  readonly publisherName: string;
  readonly packageId: string;
  readonly version: string;
  readonly manifestVersion: 2;
  readonly apiVersion: string;
  readonly runtime: 'native' | 'sandboxed-page';
  readonly packageDigest: Sha256Digest;
  readonly archiveDigest: Sha256Digest;
  readonly updatePolicy: PluginPackageUpdatePolicy;
  readonly build: {
    readonly builder: string;
    readonly buildId: string;
    readonly sourceRevision: string;
  };
  readonly provenance: {
    readonly source: string;
    readonly releaseChannel: string;
  };
  readonly issuedAt: string;
  readonly expiresAt: string | null;
  readonly signature: {
    readonly algorithm: 'Ed25519';
    readonly encoding: 'base64url';
    readonly keyId: string;
    readonly value?: string;
  };
}

export interface TrustedPublisherKeyV1 {
  readonly publisherId: string;
  readonly publisherName: string;
  readonly keyId: string;
  readonly algorithm: 'Ed25519';
  readonly publicKey: string;
  readonly validFrom: string;
  readonly validUntil: string | null;
  readonly revokedAt: string | null;
  readonly replacedByKeyId: string | null;
}

export interface SignedPluginPackageVerificationFailure {
  readonly ok: false;
  readonly code: string;
  readonly message: string;
}

export interface SignedPluginPackageVerificationSuccess {
  readonly ok: true;
  readonly status: 'verified';
  readonly publisherId: string;
  readonly publisherName: string;
  readonly keyId: string;
  readonly rotatedToKeyId: string | null;
  readonly packageId: string;
  readonly version: string;
  readonly runtime: 'native' | 'sandboxed-page';
  readonly apiVersion: string;
  readonly packageDigest: Sha256Digest;
  readonly archiveDigest: Sha256Digest;
  readonly updatePolicy: PluginPackageUpdatePolicy;
  readonly issuedAt: string;
  readonly expiresAt: string | null;
  readonly build: SignedPluginPackageMetadataV1['build'];
  readonly provenance: SignedPluginPackageMetadataV1['provenance'];
}

export type SignedPluginPackageVerificationResult =
  | SignedPluginPackageVerificationFailure
  | SignedPluginPackageVerificationSuccess;

export const SIGNED_PLUGIN_PACKAGE_SCHEMA_VERSION: 1;
export const PLUGIN_PUBLISHER_TRUST_STORE: 'thortiq-plugin-publisher-v1';
export const SIGNED_PLUGIN_PACKAGE_DOMAIN: 'thortiq-plugin-package-v1';
export const SIGNED_PLUGIN_PACKAGE_MAX_AGE_MS: number;
export const SIGNED_PLUGIN_PACKAGE_FUTURE_SKEW_MS: number;
export const TRUSTED_PUBLISHER_KEY_LIMIT: 128;

export class SignedPluginPackageError extends Error {
  readonly code: string;
}

export function parseSignedPluginPackageMetadata(
  value: unknown,
  options?: { readonly requireSignature?: boolean },
): SignedPluginPackageMetadataV1;
export function canonicalSignedPluginPackagePayload(
  value: unknown,
): Readonly<Record<string, unknown>>;
export function canonicalSignedPluginPackageBytes(value: unknown): Uint8Array;
export function attachSignedPluginPackageSignature(
  value: unknown,
  signature: Uint8Array | ArrayBuffer,
): SignedPluginPackageMetadataV1;
export function createTrustedPublisherKeyStore(
  records: readonly TrustedPublisherKeyV1[],
): {
  readonly size: number;
  get(publisherId: string, keyId: string): TrustedPublisherKeyV1 | null;
};
export function verifySignedPluginPackage(
  metadata: unknown,
  options: {
    readonly archiveDigest: Sha256Digest;
    readonly candidate: {
      readonly manifest: {
        readonly id: string;
        readonly version: string;
        readonly manifestVersion: number;
        readonly apiVersion: string;
        readonly runtime: string;
      };
      readonly digest: Sha256Digest;
    };
    readonly keyStore: {
      get(publisherId: string, keyId: string): TrustedPublisherKeyV1 | null;
    };
    readonly now?: () => number;
    readonly verifyEd25519?: (input: {
      publicKey: Uint8Array;
      signature: Uint8Array;
      bytes: Uint8Array;
    }) => Promise<boolean>;
  },
): Promise<SignedPluginPackageVerificationResult>;
export function unsignedPluginPackageVerification(input: {
  candidate: {
    manifest: {
      id: string;
      version: string;
      runtime: string;
      apiVersion: string;
    };
    digest: Sha256Digest;
  };
  archiveDigest: Sha256Digest;
  development?: boolean;
}): Readonly<Record<string, unknown>>;
export function pluginPackageProvenanceRecord(
  verification: Readonly<Record<string, unknown>>,
  input: { action: 'install' | 'update' | 'rollback'; recordedAt: string },
): Readonly<Record<string, unknown>>;
export function sha256Digest(bytes: Uint8Array | ArrayBuffer): Promise<Sha256Digest>;
export function signedPluginPackageMetadataJson(value: unknown): string;
export function signedPluginPackagePayloadText(value: unknown): string;
export function signedPluginPackagePayloadByteLength(value: unknown): number;
