import type { CancelToken } from "@vertigis/arcgis-extensions/support/Cancellable";
import type { AnalyticsContext } from "../analytics/AnalyticsContext.js";
import type { Event } from "./Event.js";
import type { Message, MessageExecuteOptions } from "./Message.js";
/**
 * A named command.
 */
export interface Command<T = void> extends Message {
    /**
     * The name of the command.
     */
    readonly name: string;
    /**
     * An event that is published whenever canExecute might return a new value.
     * Implementations are responsible for calling publish() as appropriate.
     */
    readonly canExecuteChanged: Event;
    /**
     * Indicates whether the command has been initialized.
     */
    readonly isInitialized: boolean;
    /**
     * Executes the command.
     *
     * @param argument The command arguments.
     * @param options CancelToken or options to apply to the commands execute
     *   behavior.
     */
    execute(argument: T, options?: CancelToken | MessageExecuteOptions): Promise<void>;
    /**
     * Determines whether the command can execute with the given arguments.
     *
     * @param argument The command arguments.
     */
    canExecute(argument?: T): boolean;
    /**
     * Initializes the command if it is not already initialized. Attempting to
     * execute a command will automatically initialize it, however calling
     * canExecute() will always return false until the command is initialized.
     */
    initialize(): Promise<void>;
}
/**
 * Execution context that will be passed in to each of the command's behaviors.
 */
export interface CommandContext<T> extends AnalyticsContext {
    /**
     * The name of the command that is currently executing.
     */
    readonly name: string;
    /**
     * Used to cancel execution of the command.
     */
    cancelToken?: CancelToken;
    /**
     * Determines if the command was executed from a trusted source. For
     * example, a command launched via a URL parameter should likely be
     * considered as untrusted.
     */
    trusted?: boolean;
    /**
     * Invokes the next behavior in the chain. If it isn't invoked explicitly,
     * then the next behavior will run after the current one is finished. Note
     * that this is not supported for behaviors that are added at runtime via
     * registerParallel(), which have no explicit sequence as they are run
     * concurrently.
     */
    next: (argument?: T) => Promise<void>;
    /**
     * Indicates that no more behaviors should run after the current one is
     * complete. Note that this is only supported for configured behaviors --
     * behaviors that are added at runtime via register() have no explicit
     * sequence as they are run concurrently.
     */
    finish: () => void;
}
