import type { BuildOptions } from 'esbuild';

/**
 * Options for building a Single Executable Application (SEA) with `buildSea`.
 */
export interface BuildSeaOptions {

    /** Application version included in the output directory name (e.g. `1.2.3` → `<name>-v1.2.3.<platform>-<arch>`). */
    version?: string;

    /**
     * esbuild options used to bundle the entry point into `<name>.sea.js`.
     * Must include at least `entryPoints`. When provided, `esbuild` is loaded
     * dynamically — install it with `npm install --save-dev esbuild`.
     *
     * Mutually exclusive with `config.main` — provide one or the other.
     */
    esbuild?: BuildOptions;

    /** Output directory for build artifacts (default: `./build`). */
    outDir?: string;

    /**
     * SEA configuration written to the `<name>.sea-config.json` file.
     * When `esbuild` is not provided, `main` must point to a pre-built script.
     *
     * @see https://nodejs.org/api/single-executable-applications.html#generating-single-executable-preparation-blobs
     */
    config?: {
        /** Path to the pre-built script to embed. Required when `esbuild` is not provided. */
        main: string;
        mainFormat?: 'commonjs' | 'module';
        executable?: string;
        output: string;
        disableExperimentalSEAWarning?: boolean;
        useSnapshot?: false;
        useCodeCache?: false;
        execArgv?: string[];
        execArgvExtension: 'none' | 'env' | 'cli';
        assets?: {
            [assetKey: string]: string;
        };
    };
}

/**
 * Builds a Node.js Single Executable Application (SEA).
 *
 * Provide **either** `esbuild` (to bundle an entry point on the fly) **or**
 * `config.main` (to use a pre-built script). At least one must be specified.
 *
 * When `esbuild` is provided, the entry point is bundled into `<outDir>/<name>.sea.js`
 * and that file is used as the SEA main script. Both `esbuild` and `postject` are
 * loaded lazily — they are only required as dev dependencies.
 *
 * The build is skipped when the SHA-256 of the bundled script is unchanged and the
 * target executable already exists.
 *
 * @param name - Base name for the executable and intermediate files (e.g. `gateway-server`, `io-bridge`)
 * @param options - Build options
 * @returns The path to the built executable
 */
export function buildSea(name: string, options?: BuildSeaOptions): Promise<string>;
