import { aws_events_targets, aws_stepfunctions } from "aws-cdk-lib";
import { StepFunctions } from "aws-sdk";
import { Construct } from "constructs";
import { ApiGatewayVtlIntegration } from "./api";
import { AppSyncVtlIntegration } from "./appsync";
import { ASL, ASLGraph, StateMachine, States } from "./asl";
import { Rule } from "./event-bridge";
import { EventBusTargetIntegration } from "./event-bridge/event-bus";
import { Event } from "./event-bridge/types";
import { CallExpr } from "./expression";
import { NativeIntegration } from "./function";
import { Integration, IntegrationCall } from "./integration";
export declare type AnyStepFunction = ExpressStepFunction<any, any> | StepFunction<any, any>;
/**
 * Machine and Execution context available during runtime.
 *
 * @see https://docs.aws.amazon.com/step-functions/latest/dg/input-output-contextobject.html
 *
 * To access this data, use the second parameter in a new {@link StepFunction}'s callback.
 *
 * ```ts
 * new StepFunction(stack, 'sfn', (input, context) => {
 *    return context.Execution.Name;
 * })
 * ```
 *
 * > Note: missing fields (ex: `$$.State.Name`) are abstracted away from {@link StepFunction}.
 * > Note: `$$.Execution.Input` is available as the first parameter of the closure `(input) => {}`.
 */
export interface SfnContext {
    /**
     * Data associated with the current execution of the state machine which is available during execution.
     */
    readonly Execution: {
        /**
         * Unique name of the current execution of the {@link StateMachine}.
         *
         * @example - executionName
         */
        readonly Name: string;
        /**
         * Arn of the current execution of the {@link StateMachine}.
         *
         * @example - arn:aws:states:us-east-1:123456789012:execution:stateMachineName:executionName
         */
        readonly Id: string;
        /**
         * Time the current execution started.
         *
         * Format: ISO 8601
         *
         * @example - 2019-03-26T20:14:13.192Z
         */
        readonly StartTime: string;
        /**
         * Execution role ARN
         *
         * @example - arn:aws:iam::123456789012:role
         */
        readonly RoleArn: string;
    };
    /**
     * Data associated with the state machine which is available during execution.
     */
    readonly StateMachine: {
        /**
         * Unique name of the {@link StateMachine}.
         *
         * @example - stateMachineName
         */
        readonly Name: string;
        /**
         * Arn of the {@link StateMachine}.
         *
         * @example  arn:aws:states:us-east-1:123456789012:stateMachine:stateMachineName
         */
        readonly Id: string;
    };
}
export declare type StepFunctionClosure<Payload extends Record<string, any> | undefined, Out> = (arg: Payload, context: SfnContext) => Promise<Out> | Out;
declare type ParallelFunction<T> = () => Promise<T> | T;
declare type ParallelFunctionReturnType<T extends ParallelFunction<T>> = T extends ParallelFunction<infer P> ? P : never;
export declare namespace $SFN {
    export const kind = "SFN";
    /**
     * Wait for a specific number of {@link seconds}.
     *
     * ```ts
     * new ExpressStepFunction(this, "F", (seconds: number) => $SFN.waitFor(seconds))
     * ```
     *
     * @see https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-wait-state.html
     */
    export const waitFor: IntegrationCall<"$SFN.waitFor", (seconds: number) => void>;
    /**
     * Wait until a {@link timestamp}.
     *
     * ```ts
     * new ExpressStepFunction(this, "F", (timestamp: string) => $SFN.waitUntil(timestamp))
     * ```
     *
     * @see https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-wait-state.html
     */
    export const waitUntil: IntegrationCall<"$SFN.waitUntil", (timestamp: string) => void>;
    interface ForEach {
        /**
         * Process each item in an {@link array} in parallel and run with the default maxConcurrency.
         *
         * Example:
         * ```ts
         * new ExpressStepFunction(this, "F", async (items: string[]) => {
         *   await $SFN.forEach(items, { maxConcurrency: 2 }, item => task(item));
         * });
         * ```
         *
         * @param array the list of items to process
         * @param callbackfn function to process each item
         */
        <T>(array: T[], callbackfn: (item: T, index: number, array: T[]) => void): Promise<void>;
        /**
         * Process each item in an {@link array} in parallel and run with the default maxConcurrency.
         *
         * Example:
         * ```ts
         * new ExpressStepFunction(this, "F", async (items: string[]) => {
         *   await $SFN.forEach(items, { maxConcurrency: 2 }, item => task(item));
         * });
         * ```
         *
         * @param array the list of items to process
         * @param props configure the maxConcurrency
         * @param callbackfn function to process each item
         */
        <T>(array: T[], props: {
            maxConcurrency: number;
        }, callbackfn: (item: T, index: number, array: T[]) => void): Promise<void>;
    }
    export const forEach: IntegrationCall<"$SFN.forEach", ForEach>;
    interface Map {
        /**
         * Map over each item in an {@link array} in parallel and run with the default maxConcurrency.
         *
         * Example:
         * ```ts
         * new ExpressStepFunction(this, "F", (items: string[]) => {
         *   return $SFN.map(items, item => task(item))
         * });
         * ```
         *
         * @param array the list of items to map over
         * @param callbackfn function to process each item
         * @returns an array containing the result of each mapped item
         */
        <T, U>(array: T[], callbackfn: (item: T, index: number, array: T[]) => U | Promise<U>): Promise<U[]>;
        /**
         * Map over each item in an {@link array} in parallel and run with the default maxConcurrency.
         *
         * Example:
         * ```ts
         * new ExpressStepFunction(this, "F", (items: string[]) => {
         *   return $SFN.map(items, item => task(item))
         * });
         * ```
         *
         * @param array the list of items to map over
         * @param props configure the maxConcurrency
         * @param callbackfn function to process each item
         * @returns an array containing the result of each mapped item
         */
        <T, U>(array: T[], props: {
            maxConcurrency: number;
        }, callbackfn: (item: T, index: number, array: T[]) => U | Promise<U>): Promise<U[]>;
    }
    export const map: IntegrationCall<"$SFN.map", Map>;
    /**
     * Run 1 or more workflows in parallel.
     *
     * ```ts
     * new ExpressStepFunction(this, "F", (id: string) => {
     *   const results = $SFN.parallel(
     *     () => task1(id)
     *     () => task2(id)
     *   )
     * })
     * ```
     * @param paths
     */
    export const parallel: IntegrationCall<"$SFN.parallel", <Paths extends readonly ParallelFunction<any>[]>(...paths: Paths) => Promise<{ [i in keyof Paths]: i extends `${number}` ? ParallelFunctionReturnType<Paths[i]> : Paths[i]; }>>;
    export {};
}
/**
 * Data types allowed as a Step Function Cause.
 */
export declare type StepFunctionCause = null | boolean | number | string | StepFunctionCause[] | {
    [prop: string]: StepFunctionCause;
};
/**
 * An Error that can be thrown from within a {@link StepFunction} or {@link ExpressStepFunction}.
 *
 * It encodes a `Fail` state in ASL.
 * ```json
 * {
 *   "Type": "Fail",
 *   "Error": <error>,
 *   "Cause": JSON.stringify(<cause>)
 * }
 * ```
 *
 * For example:
 * ```ts
 * throw new StepFunctionError("MyError", { "key": "value"});
 * ```
 *
 * Produces the following Fail state:
 * ```json
 * {
 *   "Type": "Fail",
 *   "Error": "MyError",
 *   "Cause": "{\"key\":\"value\""}"
 * }
 * ```
 */
export declare class StepFunctionError extends Error {
    /**
     * The name of the Error to place in the Fail state.
     */
    readonly error: string;
    readonly cause: StepFunctionCause;
    static readonly kind = "StepFunctionError";
    static isConstructor(a: any): a is typeof StepFunctionError;
    constructor(
    /**
     * The name of the Error to place in the Fail state.
     */
    error: string, cause: StepFunctionCause);
}
export declare function isStepFunction<P = any, O = any>(a: any): a is StepFunction<P, O> | ExpressStepFunction<P, O>;
/**
 * {@see https://docs.aws.amazon.com/step-functions/latest/dg/cw-events.html}
 */
interface StepFunctionDetail {
    executionArn: string;
    stateMachineArn: string;
    name: string;
    status: "SUCCEEDED" | "RUNNING" | "FAILED" | "TIMED_OUT" | "ABORTED";
    startDate: number;
    stopDate: number | null;
    input: string;
    inputDetails: {
        included: boolean;
    };
    output: null | string;
    outputDetails: null | {
        included: boolean;
    };
}
export interface StepFunctionStatusChangedEvent extends Event<StepFunctionDetail, "Step Functions Execution Status Change", "aws.states"> {
}
interface StepFunctionEventBusTargetProps extends Omit<aws_events_targets.SfnStateMachineProps, "input"> {
}
declare abstract class BaseStepFunction<Payload extends Record<string, any> | undefined, CallIn, CallOut> implements Integration<"StepFunction", (input: CallIn) => Promise<CallOut>, EventBusTargetIntegration<Payload, StepFunctionEventBusTargetProps | undefined>> {
    readonly resource: aws_stepfunctions.StateMachine;
    readonly kind = "StepFunction";
    readonly functionlessKind = "StepFunction";
    readonly appSyncVtl: AppSyncVtlIntegration;
    readonly __functionBrand: (input: CallIn) => Promise<CallOut>;
    constructor(resource: aws_stepfunctions.StateMachine);
    readonly apiGWVtl: ApiGatewayVtlIntegration;
    appSyncIntegration(integration: Pick<AppSyncVtlIntegration, "request">): AppSyncVtlIntegration;
    asl(call: CallExpr, context: ASL): ASLGraph.NodeResults;
    readonly eventBus: EventBusTargetIntegration<Payload, StepFunctionEventBusTargetProps | undefined>;
    private statusChangeEventDocument;
    onSucceeded(scope: Construct, id: string): Rule<StepFunctionStatusChangedEvent>;
    onFailed(scope: Construct, id: string): Rule<StepFunctionStatusChangedEvent>;
    onStarted(scope: Construct, id: string): Rule<StepFunctionStatusChangedEvent>;
    onTimedOut(scope: Construct, id: string): Rule<StepFunctionStatusChangedEvent>;
    onAborted(scope: Construct, id: string): Rule<StepFunctionStatusChangedEvent>;
    /**
     * Create event bus rule that matches any status change on this machine.
     */
    onStatusChanged(scope: Construct, id: string): Rule<StepFunctionStatusChangedEvent>;
}
export interface StepFunctionProps extends Omit<aws_stepfunctions.StateMachineProps, "definition" | "stateMachineType"> {
}
/**
 * An {@link ExpressStepFunction} is a callable Function which executes on the managed
 * AWS Step Function infrastructure. Like a Lambda Function, it runs within memory of
 * a single machine, except unlike Lambda, the entire environment is managed and operated
 * by AWS. Meaning, there is no Operating System, Memory, CPU, Credentials or API Clients
 * to manage. The entire workflow is configured at build-time via the Amazon State Language (ASL).
 *
 * With Functionless, the ASL is derived from type-safe TypeScript code instead of JSON.
 *
 * ```ts
 * import * as f from "functionless";
 *
 * const table = new f.Table(this, "Table", { ... });
 *
 * const getItem = new ExpressStepFunction(this, "F", () => {
 *   return f.$AWS.DynamoDB.GetItem({
 *     Table: table,
 *     Key: {
 *       ..
 *     }
 *   });
 * });
 * ```
 */
export interface IExpressStepFunction<Payload extends Record<string, any> | undefined, Out> {
    (input: StepFunctionRequest<Payload>): SyncExecutionResult<Out>;
}
declare class BaseExpressStepFunction<Payload extends Record<string, any> | undefined, Out> extends BaseStepFunction<Payload, StepFunctionRequest<Payload>, SyncExecutionResult<Out>> implements IExpressStepFunction<Payload, Out> {
    /**
     * This static property identifies this class as an ExpressStepFunction to the TypeScript plugin.
     */
    static readonly FunctionlessType = "ExpressStepFunction";
    readonly native: NativeIntegration<(input: StepFunctionRequest<Payload>) => Promise<SyncExecutionResult<Out>>>;
    constructor(machine: aws_stepfunctions.StateMachine);
}
interface BaseExpressStepFunction<Payload extends Record<string, any> | undefined, Out> {
    (input: StepFunctionRequest<Payload>): SyncExecutionResult<Out>;
}
/**
 * An {@link ExpressStepFunction} is a callable Function which executes on the managed
 * AWS Step Function infrastructure. Like a Lambda Function, it runs within memory of
 * a single machine, except unlike Lambda, the entire environment is managed and operated
 * by AWS. Meaning, there is no Operating System, Memory, CPU, Credentials or API Clients
 * to manage. The entire workflow is configured at build-time via the Amazon State Language (ASL).
 *
 * With Functionless, the ASL is derived from type-safe TypeScript code instead of JSON.
 *
 * ```ts
 * import * as f from "functionless";
 *
 * const table = new f.Table(this, "Table", { ... });
 *
 * const getItem = new ExpressStepFunction(this, "F", () => {
 *   return f.$AWS.DynamoDB.GetItem({
 *     Table: table,
 *     Key: {
 *       ..
 *     }
 *   });
 * });
 * ```
 */
export declare class ExpressStepFunction<Payload extends Record<string, any> | undefined, Out> extends BaseExpressStepFunction<Payload, Out> {
    readonly definition: StateMachine<States>;
    /**
     * Wrap a {@link aws_stepfunctions.StateMachine} with Functionless.
     *
     * A wrapped {@link StepFunction} provides common integrations like execute (`machine()`) and `describeExecution`.
     *
     * {@link ExpressStepFunction} should only be used to wrap a Express Step Function.
     * Express Step Functions should use {@link StepFunction}.
     *
     * ```ts
     * ExpressStepFunction.fromStateMachine(new aws_stepfunctions.StateMachine(this, "F", {
     *    stateMachineType: aws_stepfunctions.StateMachineType.EXPRESS,
     *    ...
     * }));
     * ```
     */
    static fromStateMachine<Payload extends Record<string, any> | undefined, Out>(machine: aws_stepfunctions.StateMachine): IExpressStepFunction<Payload, Out>;
    constructor(scope: Construct, id: string, props: StepFunctionProps, func: StepFunctionClosure<Payload, Out>);
    constructor(scope: Construct, id: string, func: StepFunctionClosure<Payload, Out>);
}
interface BaseSyncExecutionResult {
    billingDetails?: {
        billedDurationInMilliseconds: number;
        billedMemoryUsedInMB: number;
    };
    executionArn: string;
    input: string;
    inputDetails: {
        included: boolean;
    };
    name: string;
    outputDetails: {
        included: boolean;
    };
    startDate: number;
    stateMachineArn: string;
    status: "SUCCEEDED" | "FAILED" | "TIMED_OUT";
    stopDate: number;
    traceHeader: string;
}
export interface SyncExecutionFailedResult extends BaseSyncExecutionResult {
    cause: string;
    error: string;
    status: "FAILED" | "TIMED_OUT";
}
export interface SyncExecutionSuccessResult<T> extends BaseSyncExecutionResult {
    output: T;
    status: "SUCCEEDED";
}
export declare type SyncExecutionResult<T> = SyncExecutionFailedResult | SyncExecutionSuccessResult<T>;
export declare type StepFunctionRequest<P extends Record<string, any> | undefined> = (P extends undefined ? {
    input?: P;
} : {
    input: P;
}) & ({
    name: string;
    traceHeader: string;
} | {
    name: string;
} | {
    traceHeader: string;
} | {});
export interface ExpressStepFunction<Payload extends Record<string, any> | undefined, Out> {
    (input: StepFunctionRequest<Payload>): Promise<SyncExecutionResult<Out>>;
}
/**
 * A {@link StepFunction} is a callable Function which executes on the managed
 * AWS Step Function infrastructure. Like a Lambda Function, it runs within memory of
 * a single machine, except unlike Lambda, the entire environment is managed and operated
 * by AWS. Meaning, there is no Operating System, Memory, CPU, Credentials or API Clients
 * to manage. The entire workflow is configured at build-time via the Amazon State Language (ASL).
 *
 * With Functionless, the ASL is derived from type-safe TypeScript code instead of JSON.
 *
 * ```ts
 * import * as f from "functionless";
 *
 * const table = new f.Table(this, "Table", { ... });
 *
 * const getItem = new StepFunction(this, "F", () => {
 *   return f.$AWS.DynamoDB.GetItem({
 *     Table: table,
 *     Key: {
 *       ..
 *     }
 *   });
 * });
 * ```
 *
 * @typeParam Payload - the object payload to the step function.
 * @typeParam Out - the type of object the step function outputs.
 *                  currently not used: https://github.com/functionless/functionless/issues/129
 */
export interface IStepFunction<Payload extends Record<string, any> | undefined, _Out> extends Integration<"StepFunction", (input: StepFunctionRequest<Payload>) => Promise<AWS.StepFunctions.StartExecutionOutput>, EventBusTargetIntegration<Payload, StepFunctionEventBusTargetProps | undefined>> {
    describeExecution: IntegrationCall<"StepFunction.describeExecution", (executionArn: string) => Promise<AWS.StepFunctions.DescribeExecutionOutput>>;
    (input: StepFunctionRequest<Payload>): Promise<AWS.StepFunctions.StartExecutionOutput>;
}
declare class BaseStandardStepFunction<Payload extends Record<string, any> | undefined, Out> extends BaseStepFunction<Payload, StepFunctionRequest<Payload>, AWS.StepFunctions.StartExecutionOutput> implements IStepFunction<Payload, Out> {
    /**
     * This static property identifies this class as an StepFunction to the TypeScript plugin.
     */
    static readonly FunctionlessType = "StepFunction";
    readonly native: NativeIntegration<(input: StepFunctionRequest<Payload>) => Promise<AWS.StepFunctions.StartExecutionOutput>>;
    constructor(resource: aws_stepfunctions.StateMachine);
    describeExecution: IntegrationCall<"StepFunction.describeExecution", (executionArn: string) => Promise<AWS.StepFunctions.DescribeExecutionOutput>>;
}
interface BaseStandardStepFunction<Payload extends Record<string, any> | undefined, Out> {
    (input: StepFunctionRequest<Payload>): Promise<AWS.StepFunctions.StartExecutionOutput>;
}
/**
 * A {@link StepFunction} is a callable Function which executes on the managed
 * AWS Step Function infrastructure. Like a Lambda Function, it runs within memory of
 * a single machine, except unlike Lambda, the entire environment is managed and operated
 * by AWS. Meaning, there is no Operating System, Memory, CPU, Credentials or API Clients
 * to manage. The entire workflow is configured at build-time via the Amazon State Language (ASL).
 *
 * With Functionless, the ASL is derived from type-safe TypeScript code instead of JSON.
 *
 * ```ts
 * import * as f from "functionless";
 *
 * const table = new f.Table(this, "Table", { ... });
 *
 * const getItem = new StepFunction(this, "F", () => {
 *   return f.$AWS.DynamoDB.GetItem({
 *     Table: table,
 *     Key: {
 *       ..
 *     }
 *   });
 * });
 * ```
 *
 * @typeParam Payload - the object payload to the step function.
 * @typeParam Out - the type of object the step function outputs.
 *                  currently not used: https://github.com/functionless/functionless/issues/129
 */
export declare class StepFunction<Payload extends Record<string, any> | undefined, Out> extends BaseStandardStepFunction<Payload, Out> implements IStepFunction<Payload, Out> {
    readonly definition: StateMachine<States>;
    /**
     * Wrap a {@link aws_stepfunctions.StateMachine} with Functionless.
     *
     * A wrapped {@link StepFunction} provides common integrations like execute (`machine()`) and `describeExecution`.
     *
     * {@link StepFunction} should only be used to wrap a Standard Step Function.
     * Express Step Functions should use {@link ExpressStepFunction}.
     *
     * ```ts
     * StepFunction.fromStateMachine(new aws_stepfunctions.StateMachine(this, "F", {
     *    ...
     * }));
     * ```
     */
    static fromStateMachine<Payload extends Record<string, any> | undefined, Out>(machine: aws_stepfunctions.StateMachine): IStepFunction<Payload, Out>;
    constructor(scope: Construct, id: string, props: StepFunctionProps, func: StepFunctionClosure<Payload, Out>);
    constructor(scope: Construct, id: string, func: StepFunctionClosure<Payload, Out>);
}
export {};
//# sourceMappingURL=step-function.d.ts.map