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 operation. Operations compute a value, but don't generally alter the
 * state of an application.
 */
export interface Operation<T = void, TResult = undefined> extends Message {
    /**
     * The name of the operation.
     */
    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 operation has been initialized.
     */
    readonly isInitialized: boolean;
    /**
     * Executes the operation and returns its result.
     *
     * @param argument The argument to the operation.
     * @param options CancelToken or options to apply to the Operation execute
     *   behavior.
     */
    execute: (argument: T, options?: CancelToken | MessageExecuteOptions) => Promise<TResult>;
    /**
     * Determines whether the operation can execute with the given arguments.
     *
     * @param argument The operation arguments.
     */
    canExecute(argument?: T): boolean;
    /**
     * Initializes the operation if it is not already initialized. Attempting to
     * execute an operation will automatically initialize it, however calling
     * canExecute() will always return false until the operation is
     * initialized.
     */
    initialize(): Promise<void>;
}
/**
 * Context that will be passed in to each behavior for an operation.
 */
export interface OperationContext<T = void, TResult = undefined> extends AnalyticsContext {
    /**
     * The name of the operation that is currently executing.
     */
    readonly name: string;
    /**
     * The result of the previous behavior (undefined if the current behavior is
     * the first one).
     */
    result?: TResult;
    /**
     * Enables cancelling the operation (see Cancellable).
     */
    cancelToken?: CancelToken;
    /**
     * Used to determine if the operation was executed from a trusted source.
     */
    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.
     */
    next: (argument?: T, result?: TResult) => Promise<TResult>;
    /**
     * Indicates that no more behaviors should run after the current one is
     * complete. The result from the current behavior will be the final result
     * of the operation.
     */
    finish: () => void;
}
