import { Logger, FhirPackageIdentifier, PackageIndex, PackageManifest } from '@outburn/types';
export { FileInPackageIndex, PackageIndex, PackageManifest } from '@outburn/types';

/**
 * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved
 *   Project name: FHIR-Package-Installer
 */
/**
 * A basic interface for a resource file in a package
 */
interface PackageResource {
    id: string;
    resourceType: string;
    [key: string]: any | any[];
}

/**
 * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved
 *   Project name: FHIR-Package-Installer
 */

/**
 * The structure of the FPI constructor config object.
 */
interface FpiConfig {
    logger?: Logger;
    registryUrl?: string;
    registryToken?: string;
    cachePath?: string;
    skipExamples?: boolean;
    allowHttp?: boolean;
    requestTimeoutMs?: number;
    extractTimeoutMs?: number;
    /**
     * TTL (ms) for cached registry lookups (unversioned package documents, dist-tags, etc).
     * Default: 30 minutes.
     */
    registryTtlMs?: number;
}

/**
 * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved
 *   Project name: FHIR-Package-Installer
 */
/**
 * Options for the downloadPackage function.
 * @param destination The directory path where the package should be saved or extracted.
 * Defaults to the current working directory.
 * @param overwrite Whether to overwrite the existing package if it already exists.
 * Defaults to false.
 * @param extract Whether to extract the package after downloading.
 * If true, the tarball will be extracted into a subdirectory of `destination`.
 */
interface DownloadPackageOptions {
    destination?: string;
    overwrite?: boolean;
    extract?: boolean;
}

/**
 * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved
 *   Project name: FHIR-Package-Installer
 */

/**
 * Options for installing a package.
 * @param packageId Specifies a custom package ID to be installed. Defaults to the package identifier from the `package.json` file.
 * @param override Whether to override the existing package if it already exists. Defaults to false.
 * @param installDependencies Whether to install dependencies of the package. Defaults to false.
 */
interface InstallPackageOptions {
    packageId?: string | FhirPackageIdentifier;
    override?: boolean;
    installDependencies?: boolean;
}

/**
 * © Copyright Outburn Ltd. 2022-2025 All Rights Reserved
 *   Project name: FHIR-Package-Installer
 */

type GetDependenciesOptions = {
    rootPackage?: string | FhirPackageIdentifier;
    explicitImplicitVersions?: ReadonlyMap<string, string>;
    includePlanningFallbacks?: boolean;
};
declare class FhirPackageInstaller {
    private logger;
    private registryUrl;
    private registryDisabled;
    private registryToken?;
    private requestTimeoutMs;
    private extractTimeoutMs;
    private registryTtlMs;
    /**
     * Path to the FHIR package cache directory.
     * This directory is used to store downloaded and extracted FHIR packages.
     * If the directory does not exist, it will be created.
     * Default location follows FHIR spec:
     * - User apps: ~/.fhir/packages (Windows: C:\Users\<user>\.fhir\packages)
     * - System services: /var/lib/.fhir/packages (Windows: %ProgramData%\.fhir\packages)
     */
    private cachePath;
    private skipExamples;
    private allowHttp;
    private resolvingImplicitDeps;
    private installingPackages;
    private formatPackageForDebug;
    private formatMaterializationStatusForDebug;
    private describePackageInstallWaitState;
    private formatElapsedMs;
    private withDebugTiming;
    private getPackageKey;
    private normalizeDependencies;
    constructor(config?: FpiConfig);
    /**
     * Determines the default FHIR package cache path based on FHIR specifications:
     * https://confluence.hl7.org/display/FHIR/FHIR+Package+Cache
     *
     * For user applications:
     * - Windows: C:\Users\<username>\.fhir\packages
     * - Unix/Linux: ~/.fhir/packages
     *
     * For system services (daemons):
     * - Windows: %ProgramData%\.fhir\packages (typically C:\ProgramData\.fhir\packages)
     * - Unix/Linux: /var/lib/.fhir/packages
     *
     * Behavior can be overridden via the FHIR_PACKAGE_CACHE_MODE environment variable:
     * - FHIR_PACKAGE_CACHE_MODE=system -> always use system service paths
     * - FHIR_PACKAGE_CACHE_MODE=user   -> always use user paths
     */
    private getDefaultCachePath;
    private withDiskLock;
    private tryWithDiskLock;
    private ensureDiskCacheSubdir;
    private createWorkingTempDir;
    private getPackageInstallLockKey;
    private getInstallParticipantDir;
    private withInstallParticipant;
    private countActiveInstallParticipants;
    private isPackageInstallLockHeld;
    private waitForPeerDependencyHandoff;
    private withPackageInstallLock;
    private tryWithPackageInstallLock;
    private getStagingPath;
    private cleanupStaleStagingDirectories;
    private createStagingDirectory;
    private buildPackageIndexFromPackageDir;
    private normalizeIndexEntry;
    private normalizePackageIndex;
    private persistMaterializedPackageIndex;
    private tryMaterializeLegacyPackageIndex;
    private materializePackageIndex;
    private getPackageMaterializationStatus;
    private stagePackageForPublish;
    private isAlreadyExistsError;
    private isRetryableStagePublishError;
    private getDiskCacheKeyPrefix;
    private readDiskCacheJson;
    private writeDiskCacheJson;
    private writeDiskCacheJsonNoTtl;
    private getDiskRegistryMetadataCachePath;
    private getDiskIndexCachePath;
    private getDiskTarballCacheKey;
    private getDiskTarballCachePaths;
    private readDiskTarballCache;
    private writeDiskTarballDoneMarker;
    private getIndexMemKey;
    private getIndexDiskLockKey;
    private getMaterializationMarkerPath;
    private writeMaterializationMarker;
    private hasFreshMaterializationMarker;
    private isRegistryDisabled;
    private formatRegistryDisabledMessage;
    private hasShallowInstalledPackage;
    private isStrictlyMaterialized;
    private hasReadableManifest;
    private collectMissingPackages;
    private collectPlannedDependencyClosure;
    private withRetries;
    /**
     * Takes a FhirPackageIdentifier Object and returns the corresponding directory name of the package
     * @param packageObject A PackageObject with both name and version keys
     * @returns (string) Directory name in the standard format `name#version`
     */
    private toDirName;
    /**
     * Takes a FhirPackageIdentifier Object and returns the path to the package folder in the cache
     * @param packageObject A FhirPackageIdentifier Object with both name and version keys
     * @returns The full path to the package directory
     */
    getPackageDirPath(packageId: FhirPackageIdentifier | string): Promise<string>;
    /**
     * Get the full path to the .fpi.index.json file in the package folder
     * @param packageObject A FhirPackageIdentifier Object with both name and version keys
     * @returns (string) The path to the package index file
     */
    private getPackageIndexPath;
    /**
     * Scans a package folder and generates a new `.fpi.index.json` file
     * @param packageObject The package identifier object
     * @returns PackageIndex
     */
    private generatePackageIndex;
    /**
     * Generates HTTP options including authorization header for registry requests
     * @param url The URL being requested
     * @returns HTTP options object with headers if needed
     */
    private getHttpOptions;
    private fetchJson;
    private fetchStream;
    private getPackageDataFromRegistry;
    private getTarballUrl;
    private downloadFile;
    private downloadTarball;
    private getOrDownloadDiskCachedTarball;
    /**
     * Extracts a tarball to a temporary directory and generates a new `.fpi.index.json` file.
     * The tarball can be a file path or a stream.
     * @param src The source tarball, either a file path or a Readable stream.
     * @returns The path to the temporary directory where the package was extracted.
     */
    private extractTarball;
    private downloadAndExtractTarball;
    /**
     * Caches the package in the FHIR package cache directory.
     * If the package is already installed, it will not be reinstalled.
     * @param packageObject The package identifier object
     * @param src The source path of the package to be cached
     * @param move Whether to move the package to the cache or copy it. Defaults to **true**.
     * @returns The path to the cached package directory
     */
    private cachePackage;
    /**
     * Extracts the version of the package from a raw package identifier string.
     * Supported formats: `name@version`, `name#version`, or just `name`
     * @param packageId Raw package identifier string
     * @returns The version part or 'latest' if not supplied
     */
    private getVersionFromPackageString;
    isInstalled(packageId: FhirPackageIdentifier | string, options?: {
        deep?: boolean;
    }): Promise<boolean>;
    getPackageIndexFile(packageId: FhirPackageIdentifier | string): Promise<PackageIndex>;
    checkLatestPackageDist(packageName: string): Promise<string>;
    toPackageObject(packageId: string | FhirPackageIdentifier): Promise<FhirPackageIdentifier>;
    private getImplicitEffectiveCacheKey;
    private getImplicitPlanningCacheKeys;
    private readManifestFile;
    private waitForManifestDuringActiveInstall;
    getManifest(packageId: string | FhirPackageIdentifier): Promise<PackageManifest>;
    /**
     * Get the path to the FHIR package cache directory.
     * This directory is used to store downloaded and extracted FHIR packages.
     * If the directory does not exist, it will be created.
     * @returns {string} The path to the FHIR package cache directory
     */
    getCachePath(): string;
    /**
     * Get the logger instance used by this FhirPackageInstaller.
    */
    getLogger(): Logger;
    /**
     * Scan cache directory for installed versions of a package
     * @param packageName Package name to search for
     * @returns Array of installed versions sorted in descending order (latest first)
     */
    private getInstalledVersions;
    /**
     * Resolve an implicit package dependency to an effective version that is installed and manifest-valid.
     *
     * This is the materializing resolver used by code paths that need a real readable package entry,
     * not just a plannable version candidate.
     */
    protected resolveImplicitPackageVersionWithFallbacks(packageName: string): Promise<string>;
    private resolveImplicitPackageVersionForPlanning;
    /**
     * Get implicit dependencies for a given package
     * @param packageObject The package to check for implicit dependencies
     * @returns Promise resolving to record of implicit dependencies
     */
    private getImplicitDependencies;
    /**
     * Get explicit dependencies from package.json only (internal use)
     * @param packageObject The package to get explicit dependencies for
     * @returns Promise resolving to record of explicit dependencies only
     */
    private getExplicitDependencies;
    private getExplicitDependenciesFromTarballManifest;
    private getExplicitDependenciesFromRegistryMetadata;
    private getExplicitDependenciesForPlanning;
    private getDependenciesForPlanning;
    private collectExplicitDependencyClosure;
    /**
     * Get all dependencies for a package, including both explicit dependencies from package.json
     * and automatic implicit dependencies for core FHIR packages.
     *
     * For core FHIR packages (hl7.fhir.r3.core, hl7.fhir.r4.core, hl7.fhir.r5.core),
     * this automatically includes essential terminology and extension packages.
     *
     * @param packageObject The package to get dependencies for
     * @param options Optional root/context information for graph-aware implicit package version selection
     * @returns Promise resolving to record of all dependencies (explicit + implicit)
     */
    getDependencies(packageObject: FhirPackageIdentifier, options?: GetDependenciesOptions): Promise<Record<string, string>>;
    install(packageId: string | FhirPackageIdentifier): Promise<boolean>;
    private materializePackageWithoutDependencies;
    private installPackageDependencies;
    /**
     * Installs a package from a local file or directory.
     * The package can be a tarball file or a directory containing the package files.
     * @param src The path to the local package file or directory.
     * @param options Options for installing the package.
     * @returns A promise that resolves to true if the package was installed successfully,
     * or false if it was already installed.
     */
    installLocalPackage(src: string, options?: InstallPackageOptions): Promise<boolean>;
    /**
     * Downloads a package tarball and optionally extracts it to a destination directory.
     *
     * Behavior:
     * - If `extract` is false or omitted: downloads the tarball as a .tgz file to the destination directory.
     * - If `extract` is true: downloads and extracts the package into a subdirectory of the destination path.
     *
     * @param packageId A package identifier string or a FhirPackageIdentifier object.
     * @param options Options controlling the download and extraction behavior.
     * @returns
     * - If `extract` is false: the full path to the downloaded tarball file.
     * - If `extract` is true: the full path to the extracted package directory.
     */
    downloadPackage(packageId: string | FhirPackageIdentifier, options?: DownloadPackageOptions): Promise<string>;
}
/**
 * Default instance export for convenience
 */
declare const fpi: FhirPackageInstaller;

export { type DownloadPackageOptions, FhirPackageInstaller, type FpiConfig, type InstallPackageOptions, type PackageResource, fpi as default };
