import { Temporal } from "@js-temporal/polyfill";
import { URLPattern } from "urlpattern-polyfill";
import { DocumentLoader } from "./docloader-Q42SMRIB.js";
import { CryptographicKey, Multikey } from "./vocab-CzEfWQk2.js";
import { TracerProvider } from "@opentelemetry/api";

//#region sig/key.d.ts

/**
 * Generates a key pair which is appropriate for Fedify.
 * @param algorithm The algorithm to use.  Currently only RSASSA-PKCS1-v1_5 and
 *                  Ed25519 are supported.
 * @returns The generated key pair.
 * @throws {TypeError} If the algorithm is unsupported.
 */
declare function generateCryptoKeyPair(algorithm?: "RSASSA-PKCS1-v1_5" | "Ed25519"): Promise<CryptoKeyPair>;
/**
 * Exports a key in JWK format.
 * @param key The key to export.  Either public or private key.
 * @returns The exported key in JWK format.  The key is suitable for
 *          serialization and storage.
 * @throws {TypeError} If the key is invalid or unsupported.
 */
declare function exportJwk(key: CryptoKey): Promise<JsonWebKey>;
/**
 * Imports a key from JWK format.
 * @param jwk The key in JWK format.
 * @param type Which type of key to import, either `"public"` or `"private"`.
 * @returns The imported key.
 * @throws {TypeError} If the key is invalid or unsupported.
 */
declare function importJwk(jwk: JsonWebKey, type: "public" | "private"): Promise<CryptoKey>;
/**
 * Options for {@link fetchKey}.
 * @since 1.3.0
 */
interface FetchKeyOptions {
  /**
   * The document loader for loading remote JSON-LD documents.
   */
  documentLoader?: DocumentLoader;
  /**
   * The context loader for loading remote JSON-LD contexts.
   */
  contextLoader?: DocumentLoader;
  /**
   * The key cache to use for caching public keys.
   * @since 0.12.0
   */
  keyCache?: KeyCache;
  /**
   * The OpenTelemetry tracer provider to use for tracing.  If omitted,
   * the global tracer provider is used.
   * @since 1.3.0
   */
  tracerProvider?: TracerProvider;
}
/**
 * The result of {@link fetchKey}.
 * @since 1.3.0
 */
interface FetchKeyResult<T extends CryptographicKey | Multikey> {
  /**
   * The fetched (or cached) key.
   */
  readonly key: T & {
    publicKey: CryptoKey;
  } | null;
  /**
   * Whether the key is fetched from the cache.
   */
  readonly cached: boolean;
}
/**
 * Fetches a {@link CryptographicKey} or {@link Multikey} from the given URL.
 * If the given URL contains an {@link Actor} object, it tries to find
 * the corresponding key in the `publicKey` or `assertionMethod` property.
 * @typeParam T The type of the key to fetch.  Either {@link CryptographicKey}
 *              or {@link Multikey}.
 * @param keyId The URL of the key.
 * @param cls The class of the key to fetch.  Either {@link CryptographicKey}
 *            or {@link Multikey}.
 * @param options Options for fetching the key.  See {@link FetchKeyOptions}.
 * @returns The fetched key or `null` if the key is not found.
 * @since 1.3.0
 */
declare function fetchKey<T extends CryptographicKey | Multikey>(keyId: URL | string, cls: (new (...args: any[]) => T) & {
  fromJsonLd(jsonLd: unknown, options: {
    documentLoader?: DocumentLoader;
    contextLoader?: DocumentLoader;
    tracerProvider?: TracerProvider;
  }): Promise<T>;
}, options?: FetchKeyOptions): Promise<FetchKeyResult<T>>;
/**
 * A cache for storing cryptographic keys.
 * @since 0.12.0
 */
interface KeyCache {
  /**
   * Gets a key from the cache.
   * @param keyId The key ID.
   * @returns The key if found, `null` if the key is not available (e.g.,
   *          fetching the key was tried but failed), or `undefined`
   *          if the cache is not available.
   */
  get(keyId: URL): Promise<CryptographicKey | Multikey | null | undefined>;
  /**
   * Sets a key to the cache.
   *
   * Note that this caches unavailable keys (i.e., `null`) as well,
   * and it is recommended to make unavailable keys expire after a short period.
   * @param keyId The key ID.
   * @param key The key to cache.  `null` means the key is not available
   *            (e.g., fetching the key was tried but failed).
   */
  set(keyId: URL, key: CryptographicKey | Multikey | null): Promise<void>;
}
//#endregion
//#region sig/http.d.ts
/**
 * The standard to use for signing and verifying HTTP signatures.
 * @since 1.6.0
 */
type HttpMessageSignaturesSpec =
/**
 * The Signing HTTP Messages (draft-cavage-http-signatures-12) specification,
 * which is widely adopted and used in the fediverse (as of May 2025).
 */
"draft-cavage-http-signatures-12"
/**
 * The HTTP Message Signatures (RFC 9421) specification, which is the
 * finalized standard but not widely adopted yet (as of May 2025).
 */ | "rfc9421";
/**
 * Options for {@link signRequest}.
 * @since 1.3.0
 */
interface SignRequestOptions {
  /**
   * The HTTP message signatures specification to use for signing.
   * @default `"draft-cavage-http-signatures-12"`
   * @since 1.6.0
   */
  spec?: HttpMessageSignaturesSpec;
  /**
   * The current time.  If not specified, the current time is used.  This is
   * useful for testing.
   * @since 1.6.0
   */
  currentTime?: Temporal.Instant;
  /**
   * The request body as ArrayBuffer. If provided, avoids cloning the request body.
   * @since 1.7.7
   */
  body?: ArrayBuffer | null;
  /**
   * The OpenTelemetry tracer provider.  If omitted, the global tracer provider
   * is used.
   */
  tracerProvider?: TracerProvider;
}
/**
 * Signs a request using the given private key.
 * @param request The request to sign.
 * @param privateKey The private key to use for signing.
 * @param keyId The key ID to use for the signature.  It will be used by the
 *              verifier.
 * @returns The signed request.
 * @throws {TypeError} If the private key is invalid or unsupported.
 */
declare function signRequest(request: Request, privateKey: CryptoKey, keyId: URL, options?: SignRequestOptions): Promise<Request>;
/**
 * Options for {@link verifyRequest}.
 */
interface VerifyRequestOptions {
  /**
   * The document loader to use for fetching the public key.
   */
  documentLoader?: DocumentLoader;
  /**
   * The context loader to use for JSON-LD context retrieval.
   */
  contextLoader?: DocumentLoader;
  /**
   * The time window to allow for the request date.  The actual time window is
   * twice the value of this option, with the current time as the center.
   * Or if it is `false`, no time check is performed.
   *
   * An hour by default.
   */
  timeWindow?: Temporal.Duration | Temporal.DurationLike | false;
  /**
   * The current time.  If not specified, the current time is used.  This is
   * useful for testing.
   */
  currentTime?: Temporal.Instant;
  /**
   * The key cache to use for caching public keys.
   * @since 0.12.0
   */
  keyCache?: KeyCache;
  /**
   * The HTTP message signatures specification to use for verifying.
   * @default `"draft-cavage-http-signatures-12"`
   * @since 1.6.0
   */
  spec?: HttpMessageSignaturesSpec;
  /**
   * The OpenTelemetry tracer provider.  If omitted, the global tracer provider
   * is used.
   * @since 1.3.0
   */
  tracerProvider?: TracerProvider;
}
/**
 * Verifies the signature of a request.
 *
 * Note that this function consumes the request body, so it should not be used
 * if the request body is already consumed.  Consuming the request body after
 * calling this function is okay, since this function clones the request
 * under the hood.
 *
 * @param request The request to verify.
 * @param options Options for verifying the request.
 * @returns The public key of the verified signature, or `null` if the signature
 *          could not be verified.
 */
declare function verifyRequest(request: Request, options?: VerifyRequestOptions): Promise<CryptographicKey | null>;
/**
 * A spec determiner for HTTP Message Signatures.
 * It determines the spec to use for signing requests.
 * It is used for double-knocking
 * (see <https://swicg.github.io/activitypub-http-signature/#how-to-upgrade-supported-versions>).
 * @since 1.6.0
 */
interface HttpMessageSignaturesSpecDeterminer {
  /**
   * Determines the spec to use for signing requests.
   * @param origin The origin of the URL to make the request to.
   * @returns The spec to use for signing requests.
   */
  determineSpec(origin: string): HttpMessageSignaturesSpec | Promise<HttpMessageSignaturesSpec>;
  /**
   * Remembers the successfully used spec for the given origin.
   * @param origin The origin of the URL that was requested.
   * @param spec The spec to remember.
   */
  rememberSpec(origin: string, spec: HttpMessageSignaturesSpec): void | Promise<void>;
}
/**
 * The options for double-knock requests.
 * @since 1.6.0
 */
//#endregion
export { FetchKeyOptions, FetchKeyResult, HttpMessageSignaturesSpec, HttpMessageSignaturesSpecDeterminer, KeyCache, SignRequestOptions, VerifyRequestOptions, exportJwk, fetchKey, generateCryptoKeyPair, importJwk, signRequest, verifyRequest };