import { InputLogObject } from 'consola';
import { RimrafAsyncOptions } from 'rimraf';

/**
 * Declaration for file input/output patterns.
 */
interface FileDeclaration {
    /** The declaration type, always "file". */
    readonly type: "file";
    /** Glob patterns or paths matching files. */
    readonly patterns: string[];
}
/**
 * Declaration for directory input/output patterns.
 */
interface DirDeclaration {
    /** The declaration type, always "dir". */
    readonly type: "dir";
    /** Glob patterns or paths matching directories. */
    readonly patterns: string[];
}
/**
 * Union type for file or directory declarations.
 */
type Declaration = FileDeclaration | DirDeclaration;

/**
 * Namespace for declaring file and directory input patterns for caching.
 */
declare namespace Inputs {
    /**
     * Declare file input patterns for caching.
     * @param patterns - Glob patterns matching files.
     * @returns FileDeclaration object.
     */
    function files(...patterns: string[]): FileDeclaration;
    /**
     * Declare directory input patterns for caching.
     * @param patterns - Glob patterns matching directories.
     * @returns DirDeclaration object.
     */
    function dirs(...patterns: string[]): DirDeclaration;
}
/**
 * Utilities for declaring file and directory output patterns for caching.
 *
 * These are aliases of {@link Inputs.files} and {@link Inputs.dirs}.
 */
declare namespace Outputs {
    /**
     * Declare file output patterns for caching.
     * @see Inputs.files
     */
    const files: typeof Inputs.files;
    /**
     * Declare directory output patterns for caching.
     * @see Inputs.dirs
     */
    const dirs: typeof Inputs.dirs;
}

/**
 * Supported log levels for Nadle.
 */
declare const SupportLogLevels: ["error", "log", "info", "debug"];
/**
 * Type representing supported log levels.
 */
type SupportLogLevel = (typeof SupportLogLevels)[number];

/**
 * Available output reporters.
 *
 * - `default`: human-oriented output with colors and an optional in-progress footer.
 * - `agent`: compact, plain, low-noise output for AI agents and scripts.
 */
declare const SupportReporters: readonly ["default", "agent"];
/** A supported output reporter name. */
type SupportReporter = (typeof SupportReporters)[number];

/**
 * Base options for Nadle configuration.
 */
interface NadleBaseOptions {
    /** Enable or disable caching. */
    readonly cache?: boolean;
    /** Directory to store cache files. */
    readonly cacheDir?: string;
    /** Show footer in output. */
    readonly footer?: boolean;
    /** Enable or disable parallel task execution. */
    readonly parallel?: boolean;
    /** Maximum number of cache entries to keep per task. Oldest are evicted when exceeded. */
    readonly maxCacheEntries?: number;
    /** Output reporter to use. */
    readonly reporter?: SupportReporter;
    /** Log level for reporting. */
    readonly logLevel?: SupportLogLevel;
    /** Minimum number of worker threads (number or string, e.g., "50%"). */
    readonly minWorkers?: number | string;
    /** Maximum number of worker threads (number or string, e.g., "100%"). */
    readonly maxWorkers?: number | string;
    /** Enable or disable implicit workspace task dependencies. */
    readonly implicitDependencies?: boolean;
}
/**
 * File-based options for Nadle configuration.
 */
interface NadleFileOptions extends Partial<NadleBaseOptions> {
    /** Task alias configuration. */
    readonly alias?: AliasOption;
}
/**
 * Alias configuration for tasks.
 * Can be a record of alias mappings or a function returning an alias for a workspace path.
 */
type AliasOption = Record<string, string> | ((workspacePath: string) => string | undefined);

/**
 * Configure Nadle with global file options.
 *
 * Registers the provided options object for use in Nadle's build process.
 *
 * @param options - The Nadle file options to register.
 * @throws {TypeError} If options is not an object.
 */
declare function configure(options: NadleFileOptions): void;

/**
 * Utility type representing a value that can be a single item or an array of items.
 */
type MaybeArray<T> = T | T[];
/**
 * Namespace for MaybeArray utility functions.
 */
declare namespace MaybeArray {
    /**
     * Converts a value that may be a single item or an array into an array.
     * @param value - The value to convert.
     * @returns The value as an array.
     */
    function toArray<T>(value: MaybeArray<T>): T[];
}

/**
 * Generic callback type.
 * @template T Return type.
 * @template P Parameter type.
 */
type Callback<T = unknown, P = void> = (params: P) => T;
/**
 * A value or a callback returning a value.
 * @template T The resolved type.
 */
type Resolver<T = unknown> = T | Callback<T>;
/**
 * A type representing a value or a promise of a value.
 */
type Awaitable<T> = T | PromiseLike<T>;

/**
 * Error class for Nadle with a typed exit code.
 *
 * @public
 */
declare class NadleError extends Error {
    /**
     * The process exit code to use when this error is caught at the top level.
     */
    readonly errorCode: number;
    constructor(message: string, errorCode?: number, options?: ErrorOptions);
}
/**
 * Thrown when configuration is invalid or cannot be loaded — a missing or
 * malformed config file, invalid options, or invalid task inputs.
 *
 * @public
 */
declare class ConfigurationError extends NadleError {
    constructor(message: string);
}
/**
 * Thrown when a requested task cannot be resolved within the project.
 *
 * @public
 */
declare class TaskNotFoundError extends NadleError {
    constructor(message: string);
}
/**
 * Thrown when the task graph contains a cyclic dependency.
 *
 * @public
 */
declare class CyclicDependencyError extends NadleError {
    constructor(message: string);
}
/**
 * Thrown when a task fails during execution.
 *
 * @public
 */
declare class TaskExecutionError extends NadleError {
    constructor(message: string, options?: ErrorOptions);
}

/**
 * Logger interface for Nadle.
 */
interface Logger {
    /**
     * Log a standard message.
     * @param message - The message or log object.
     * @param args - Additional arguments.
     */
    log(message: InputLogObject | string, ...args: unknown[]): void;
    /**
     * Log a warning message.
     * @param message - The message or log object.
     * @param args - Additional arguments.
     */
    warn(message: InputLogObject | string, ...args: unknown[]): void;
    /**
     * Log an info message.
     * @param message - The message or log object.
     * @param args - Additional arguments.
     */
    info(message: InputLogObject | string, ...args: unknown[]): void;
    /**
     * Log an error message.
     * @param message - The message or log object.
     * @param args - Additional arguments.
     */
    error(message: InputLogObject | string, ...args: unknown[]): void;
    /**
     * Log a debug message.
     * @param message - The message or log object.
     * @param args - Additional arguments.
     */
    debug(message: InputLogObject | string, ...args: unknown[]): void;
    /**
     * Get the number of columns in the output stream.
     * @returns Number of columns, or 80 if unavailable.
     */
    getColumns(): number;
}

/**
 * Interface for a typed task with options.
 * @template Options The options type for the task.
 */
interface Task<Options = unknown> {
    /**
     * The function to run for this task.
     * @param options - Task options.
     * @param context - Runner context.
     */
    run: Callback<Awaitable<void>, {
        options: Options;
        context: RunnerContext;
    }>;
}
/**
 * Context object passed to task runners.
 */
interface RunnerContext {
    /** Logger instance for reporting. */
    readonly logger: Logger;
    /** The working directory for the task. */
    readonly workingDir: string;
    /** Arguments after `--` on the CLI. Empty unless this task was explicitly requested. */
    readonly passthroughArgs: readonly string[];
}

/**
 * Configuration for a Nadle task.
 */
interface TaskConfiguration {
    /**
     * The group name to which this task belongs.
     */
    group?: string;
    /**
     * The description of the task.
     */
    description?: string;
    /**
     * A task or a list of tasks that this task depends on.
     */
    dependsOn?: MaybeArray<string>;
    /**
     * Environment variables to set when running the task.
     */
    env?: TaskEnv;
    /**
     * Changes the working directory for the task.
     */
    workingDir?: string;
    /**
     * Input declaration for the task.
     * Declare any files, directories or globs that the task reads from.
     * These are used for cache key generation.
     */
    inputs?: MaybeArray<Declaration>;
    /**
     * Output declaration for the task.
     * Declare any files or directories that the task produces.
     * These are used for caching, restoring, and cleanup.
     */
    outputs?: MaybeArray<Declaration>;
    /**
     * Maximum number of cache entries to keep for this task.
     * When exceeded, the oldest entries are evicted.
     * Overrides the global `maxCacheEntries` setting.
     */
    maxCacheEntries?: number;
}
/**
 * Environment variables for a task.
 */
type TaskEnv = Record<string, string | number | boolean>;

/**
 * The main API for registering tasks in Nadle.
 *
 * Provides overloaded `register` methods for defining tasks with or without options and custom resolvers.
 * Each method returns a TaskConfigurationBuilder for further configuration.
 */
interface TasksAPI {
    /**
     * Register a task by name only.
     * @param name - The unique name of the task.
     * @returns ConfigBuilder for further configuration.
     */
    register(name: string): TaskConfigurationBuilder;
    /**
     * Register a task with options and a resolver.
     *
     * The resolver may be omitted when the task's options have no required fields
     * (i.e. an empty object satisfies `Options`); otherwise it is mandatory.
     * @param name - The unique name of the task.
     * @param optTask - The task definition with options.
     * @param optionsResolver - A resolver for the task's options.
     * @returns ConfigBuilder for further configuration.
     */
    register<Options>(name: string, optTask: Task<Options>, ...optionsResolver: {} extends Options ? [optionsResolver?: Resolver<Options>] : [optionsResolver: Resolver<Options>]): TaskConfigurationBuilder;
    /**
     * Register a task with a task function.
     * @param name - The unique name of the task.
     * @param fnTask - The function to execute for this task.
     * @returns ConfigBuilder for further configuration.
     */
    register(name: string, fnTask: TaskFn): TaskConfigurationBuilder;
}
/**
 * Builder interface for configuring a task.
 */
interface TaskConfigurationBuilder {
    /**
     * Configure the task with a configuration object or builder callback.
     * @param builder - Task configuration or a callback returning configuration.
     */
    config(builder: Callback<TaskConfiguration> | TaskConfiguration): void;
}
/**
 * Function signature for a basic task.
 */
type TaskFn = Callback<Awaitable<void>, {
    context: RunnerContext;
}>;
/**
 * The main tasks API instance for registering tasks in Nadle.
 *
 * Use this object to register new tasks and configure them using the fluent API.
 *
 * Example:
 * ```ts
 * tasks.register("build", async ({ context }) => { ... }).config({ ... });
 * ```
 */
declare const tasks: TasksAPI;

/**
 * Parameters for defining a task.
 */
interface DefineTaskParams<Options> extends Task<Options> {
}
/**
 * Define a task with the given parameters.
 *
 * @param params - The task parameters.
 * @returns The defined task.
 */
declare function defineTask<Options>(params: DefineTaskParams<Options>): Task<Options>;

/**
 * Options for the NpmTask.
 */
interface NpmTaskOptions {
    /** Arguments to pass to the npm CLI. */
    readonly args: MaybeArray<string>;
}
/**
 * Task for running npm commands.
 *
 * Executes npm with the provided arguments in the given working directory.
 */
declare const NpmTask: Task<NpmTaskOptions>;

/**
 * Options for the NpxTask.
 */
interface NpxTaskOptions {
    /** The command to execute via npx. */
    readonly command: string;
    /** Arguments for the command. Defaults to none. */
    readonly args?: MaybeArray<string>;
}
/**
 * Task for running locally-installed package binaries via npx.
 *
 * Executes `npx <command> <args>` in the given working directory.
 */
declare const NpxTask: Task<NpxTaskOptions>;

/**
 * Selects files relative to a base directory using glob patterns.
 *
 * @public
 */
interface FileSelector {
    /** Base directory the patterns are matched against. */
    readonly dir: string;
    /** Glob patterns to include. Defaults to all files. */
    readonly include?: MaybeArray<string>;
    /** Glob patterns to exclude. */
    readonly exclude?: MaybeArray<string>;
}
/**
 * A source of files for file-operation tasks: a path to a file or directory,
 * or a {@link FileSelector} with glob patterns.
 *
 * @public
 */
type FileSelection = string | FileSelector;

/**
 * Options for the ZipTask.
 */
interface ZipTaskOptions {
    /** Path of the zip archive to create (relative to working directory). */
    readonly archive: string;
    /** Entry-name prefix, e.g. `"bundle"` stores files as `bundle/...`. */
    readonly prefix?: string;
    /** Fail when a source path is missing or no files match. Defaults to false. */
    readonly strict?: boolean;
    /** Default include patterns for directory selections without their own. */
    readonly include?: MaybeArray<string>;
    /** Default exclude patterns for directory selections without their own. */
    readonly exclude?: MaybeArray<string>;
    /** Source file(s), directory(ies), or selector(s) with glob patterns. */
    readonly from: MaybeArray<FileSelection>;
}
/**
 * Task for creating a zip archive from selected files.
 *
 * Entry names are the selection-relative paths, optionally under `prefix`.
 */
declare const ZipTask: Task<ZipTaskOptions>;

/**
 * Options for the NodeTask.
 */
interface NodeTaskOptions {
    /** The script to execute via node. */
    readonly script: string;
    /** Arguments for the script. Defaults to none. */
    readonly args?: MaybeArray<string>;
}
/**
 * Task for running Node.js scripts.
 *
 * Executes `node <script> <args>` in the given working directory.
 */
declare const NodeTask: Task<NodeTaskOptions>;

/**
 * Options for the PnpmTask.
 */
interface PnpmTaskOptions {
    /** Arguments to pass to the pnpm CLI. */
    readonly args: MaybeArray<string>;
    /** Workspace package(s) to scope the command to, passed as pnpm `--filter` flags. */
    readonly filter?: MaybeArray<string>;
}
/**
 * Task for running pnpm commands.
 *
 * Executes pnpm with the provided arguments in the given working directory.
 * When `filter` is set, each value is prepended as a `--filter <value>` flag so
 * the command runs only in the matching workspace package(s).
 */
declare const PnpmTask: Task<PnpmTaskOptions>;

/**
 * Options for the PnpxTask.
 */
interface PnpxTaskOptions {
    /** The command to execute via pnpm exec. */
    readonly command: string;
    /** Arguments for the command. Defaults to none. */
    readonly args?: MaybeArray<string>;
}
/**
 * Task for running locally-installed package binaries via pnpm exec.
 *
 * Executes `pnpm exec <command> <args>` in the given working directory.
 */
declare const PnpxTask: Task<PnpxTaskOptions>;

/**
 * Options for the ExecTask.
 */
interface ExecTaskOptions {
    /** The command to execute. */
    readonly command: string;
    /** Arguments for the command (array or string). Defaults to none. */
    readonly args?: MaybeArray<string>;
}
/**
 * Task for executing arbitrary shell commands.
 *
 * Supports both string and array arguments.
 */
declare const ExecTask: Task<ExecTaskOptions>;

/**
 * Options shared by the file-operation tasks (Copy, Move, Sync).
 *
 * @public
 */
interface FileOperationOptions {
    /** Destination directory. Created if missing. */
    readonly into: string;
    /** Fail when a source path is missing or no files match. Defaults to false. */
    readonly strict?: boolean;
    /** Place all files directly into `into`, dropping source directory structure. */
    readonly flatten?: boolean;
    /** Default include patterns for directory selections without their own. */
    readonly include?: MaybeArray<string>;
    /** Default exclude patterns for directory selections without their own. */
    readonly exclude?: MaybeArray<string>;
    /** Source file(s), directory(ies), or selector(s) with glob patterns. */
    readonly from: MaybeArray<FileSelection>;
    /** Renames by exact base name, e.g. `{ "config.dev.json": "config.json" }`. */
    readonly rename?: Record<string, string>;
}
/** Overwrite policy applied per existing destination file. */
type OverwritePolicy = "error" | "replace" | "skip";

/**
 * Options for the CopyTask.
 */
interface CopyTaskOptions extends FileOperationOptions {
    /** Behavior when a destination file already exists. Defaults to `replace`. */
    readonly overwrite?: OverwritePolicy;
}
/**
 * Task for copying files and directories.
 *
 * Sources are files, directories, or glob selectors; the destination (`into`) is
 * always a directory. Supports flattening, renaming, and overwrite policies.
 */
declare const CopyTask: Task<CopyTaskOptions>;

/**
 * Options for the MoveTask.
 */
interface MoveTaskOptions extends FileOperationOptions {
    /** Behavior when a destination file already exists. Defaults to `replace`. */
    readonly overwrite?: OverwritePolicy;
}
/**
 * Task for moving files and directories.
 *
 * Same selection semantics as CopyTask, but sources are removed after the move.
 * Uses a rename syscall when possible and falls back to copy-then-delete (e.g.
 * across devices). Skipped files (overwrite policy) keep their source.
 */
declare const MoveTask: Task<MoveTaskOptions>;

/**
 * Options for the SyncTask.
 */
interface SyncTaskOptions extends FileOperationOptions {
    /** Glob patterns (relative to `into`) for files that are never deleted. */
    readonly preserve?: MaybeArray<string>;
}
/**
 * Task for mirroring sources into a destination directory.
 *
 * Same selection semantics as CopyTask, but after copying, files in `into` that do
 * not correspond to a source (and do not match `preserve`) are deleted, and empty
 * directories are pruned. The destination ends up as an exact mirror.
 */
declare const SyncTask: Task<SyncTaskOptions>;

/**
 * Options for the UnzipTask.
 */
interface UnzipTaskOptions {
    /** Destination directory. Created if missing. */
    readonly into: string;
    /** Path of the zip archive to extract (relative to working directory). */
    readonly archive: string;
    /** Glob patterns selecting which entries to extract. Defaults to all. */
    readonly include?: MaybeArray<string>;
}
/**
 * Task for extracting a zip archive into a directory.
 */
declare const UnzipTask: Task<UnzipTaskOptions>;

/**
 * Options for the DeleteTask.
 * Extends RimrafAsyncOptions and adds required paths property.
 */
interface DeleteTaskOptions extends RimrafAsyncOptions {
    /** File or directory paths (glob or array of globs) to delete. */
    readonly paths: MaybeArray<string>;
}
/**
 * Task for deleting files and directories using glob patterns.
 *
 * Uses rimraf for deletion and supports all rimraf async options.
 */
declare const DeleteTask: Task<DeleteTaskOptions>;

/**
 * Options for the DownloadTask.
 */
interface DownloadTaskOptions {
    /** The URL to download. */
    readonly url: string;
    /** Destination directory. Created if missing. */
    readonly into: string;
    /** Expected SHA-256 hex digest; the task fails on mismatch. */
    readonly sha256?: string;
    /** Destination file name. Defaults to the last segment of the URL path. */
    readonly filename?: string;
}
/**
 * Task for downloading a file over HTTP(S).
 *
 * When `sha256` is given and the destination file already exists with a matching
 * digest, the download is skipped. A digest mismatch after download fails the task
 * and removes the file.
 */
declare const DownloadTask: Task<DownloadTaskOptions>;

export { type AliasOption, type Awaitable, type Callback, ConfigurationError, CopyTask, type CopyTaskOptions, CyclicDependencyError, type Declaration, type DefineTaskParams, DeleteTask, type DeleteTaskOptions, type DirDeclaration, DownloadTask, type DownloadTaskOptions, ExecTask, type ExecTaskOptions, type FileDeclaration, type FileOperationOptions, type FileSelection, type FileSelector, Inputs, type Logger, MaybeArray, MoveTask, type MoveTaskOptions, type NadleBaseOptions, NadleError, type NadleFileOptions, NodeTask, type NodeTaskOptions, NpmTask, type NpmTaskOptions, NpxTask, type NpxTaskOptions, Outputs, type OverwritePolicy, PnpmTask, type PnpmTaskOptions, PnpxTask, type PnpxTaskOptions, type Resolver, type RunnerContext, type SupportLogLevel, SupportLogLevels, type SupportReporter, SupportReporters, SyncTask, type SyncTaskOptions, type Task, type TaskConfiguration, type TaskConfigurationBuilder, type TaskEnv, TaskExecutionError, type TaskFn, TaskNotFoundError, type TasksAPI, UnzipTask, type UnzipTaskOptions, ZipTask, type ZipTaskOptions, configure, defineTask, tasks };
