import { AWSError, CloudWatchLogs, IAM, Lambda, Pricing, Request, S3, SNS, SQS, STS } from "aws-sdk";
import { ConfigurationOptions } from "aws-sdk/lib/config-base";
import { CostSnapshot } from "../cost";
import { PackerResult } from "../packer";
import { CleanupOptions, CommonOptions, FunctionStats, ProviderImpl } from "../provider";
import { WrapperOptions } from "../wrapper";
import { AwsLayerInfo } from "./aws-npm";
export declare const defaultGcWorker: (work: AwsGcWork, services: AwsServices) => Promise<void>;
/**
 * AWS-specific options for {@link faastAws}.
 * @public
 */
export interface AwsOptions extends CommonOptions {
    /**
     * The region to create resources in. Garbage collection is also limited to
     * this region. Default: `"us-west-2"`.
     */
    region?: AwsRegion;
    /**
     * The role that the lambda function will assume when executing user code.
     * Default: `"faast-cached-lambda-role"`. Rarely used.
     * @remarks
     * When a lambda executes, it first assumes an
     * {@link https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html | execution role}
     * to grant access to resources.
     *
     * By default, faast.js creates this execution role for you and leaves it
     * permanently in your account (the role is shared across all lambda
     * functions created by faast.js). By default, faast.js grants administrator
     * privileges to this role so your code can perform any AWS operation it
     * requires.
     *
     * You can
     * {@link https://console.aws.amazon.com/iam/home#/roles | create a custom role}
     * that specifies more limited permissions if you prefer not to grant
     * administrator privileges. Any role you assign for faast.js modules needs
     * at least the following permissions:
     *
     * - Execution Role:
     * ```json
     *   {
     *       "Version": "2012-10-17",
     *       "Statement": [
     *           {
     *               "Effect": "Allow",
     *               "Action": ["logs:*"],
     *               "Resource": "arn:aws:logs:*:*:log-group:faast-*"
     *           },
     *           {
     *               "Effect": "Allow",
     *               "Action": ["sqs:*"],
     *               "Resource": "arn:aws:sqs:*:*:faast-*"
     *           }
     *       ]
     *   }
     * ```
     *
     * - Trust relationship (also known as `AssumeRolePolicyDocument` in the AWS
     *   SDK):
     * ```json
     *   {
     *     "Version": "2012-10-17",
     *     "Statement": [
     *       {
     *         "Effect": "Allow",
     *         "Principal": {
     *           "Service": "lambda.amazonaws.com"
     *         },
     *         "Action": "sts:AssumeRole"
     *       }
     *     ]
     *   }
     * ```
     *
     */
    RoleName?: string;
    /**
     * Additional options to pass to AWS Lambda creation. See
     * {@link https://docs.aws.amazon.com/lambda/latest/dg/API_CreateFunction.html | CreateFunction}.
     * @remarks
     * If you need specialized options, you can pass them to the AWS Lambda SDK
     * directly. Note that if you override any settings set by faast.js, you may
     * cause faast.js to not work:
     *
     * ```typescript
     *   const request: aws.Lambda.CreateFunctionRequest = {
     *       FunctionName,
     *       Role,
     *       Runtime: "nodejs14.x",
     *       Handler: "index.trampoline",
     *       Code,
     *       Description: "faast trampoline function",
     *       Timeout,
     *       MemorySize,
     *       ...awsLambdaOptions
     *   };
     * ```
     */
    awsLambdaOptions?: Partial<Lambda.CreateFunctionRequest>;
    /**
     * Additional options to pass to all AWS services. See
     * {@link https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Config.html | AWS.Config}.
     * @remarks
     * If you need to specify AWS options such as credentials, you can pass set
     * these options here. Note that faast.js will override some options even if
     * they are specified here, specifically the options used to create the
     * `Lambda` service, to ensure they allow for faast to function correctly.
     * Options set in {@link CommonOptions} override those set here.
     *
     * Example of passing in credentials:
     *
     * ```typescript
     *   const credentials = { accessKeyId, secretAccessKey };
     *   const m = await faastAws(funcs, { credentials });
     * ```
     */
    awsConfig?: ConfigurationOptions;
    /** @internal */
    _gcWorker?: (work: AwsGcWork, services: AwsServices) => Promise<void>;
}
export declare let defaults: Required<AwsOptions>;
export interface AwsPrices {
    lambdaPerRequest: number;
    lambdaPerGbSecond: number;
    snsPer64kPublish: number;
    sqsPer64kRequest: number;
    dataOutPerGb: number;
    logsIngestedPerGb: number;
}
export declare class AwsMetrics {
    outboundBytes: number;
    sns64kRequests: number;
    sqs64kRequests: number;
}
export interface AwsResources {
    FunctionName: string;
    RoleName: string;
    region: AwsRegion;
    ResponseQueueUrl?: string;
    ResponseQueueArn?: string;
    RequestTopicArn?: string;
    SNSLambdaSubscriptionArn?: string;
    logGroupName: string;
    layer?: AwsLayerInfo;
    Bucket?: string;
}
export interface AwsServices {
    readonly lambda: Lambda;
    readonly lambda2: Lambda;
    readonly cloudwatch: CloudWatchLogs;
    readonly iam: IAM;
    readonly sqs: SQS;
    readonly sns: SNS;
    readonly pricing: Pricing;
    readonly sts: STS;
    readonly s3: S3;
}
/**
 * @public
 */
export interface AwsState {
    /** @internal */
    resources: AwsResources;
    /** @internal */
    services: AwsServices;
    /** @internal */
    options: Required<AwsOptions>;
    /** @internal */
    metrics: AwsMetrics;
    /** @internal */
    gcPromise?: Promise<"done" | "skipped">;
}
export declare type AwsGcWork = {
    type: "SetLogRetention";
    logGroupName: string;
    retentionInDays: number;
} | {
    type: "DeleteResources";
    resources: AwsResources;
} | {
    type: "DeleteLayerVersion";
    LayerName: string;
    VersionNumber: number;
};
export declare function carefully<U>(arg: Request<U, AWSError>): Promise<import("aws-sdk/lib/request").PromiseResult<U, AWSError> | undefined>;
export declare function quietly<U>(arg: Request<U, AWSError>): Promise<import("aws-sdk/lib/request").PromiseResult<U, AWSError> | undefined>;
export declare const createAwsApis: (region: AwsRegion, awsConfig?: ConfigurationOptions | undefined) => Promise<AwsServices>;
export declare function ensureRoleRaw(RoleName: string, services: AwsServices, createRole: boolean): Promise<IAM.Role>;
export declare const ensureRole: (RoleName: string, services: AwsServices, createRole: boolean) => Promise<IAM.Role>;
export declare function createLayer(lambda: Lambda, packageJson: string | object | undefined, useDependencyCaching: boolean, FunctionName: string, region: AwsRegion, retentionInDays: number, awsLambdaOptions: Partial<Lambda.CreateFunctionRequest>): Promise<AwsLayerInfo | undefined>;
export declare function logUrl(state: AwsState): string;
export declare const initialize: (fModule: string, nonce: string, options: Required<AwsOptions>) => Promise<AwsState>;
export declare function deleteRole(RoleName: string, iam: IAM): Promise<void>;
export declare function deleteResources(resources: Partial<AwsResources>, services: AwsServices, output?: (msg: string) => void): Promise<void>;
export declare function cleanup(state: AwsState, options: Required<CleanupOptions>): Promise<void>;
export declare function clearLastGc(): void;
export declare function collectGarbage(executor: typeof defaultGcWorker, services: AwsServices, region: AwsRegion, retentionInDays: number, mode: "auto" | "force"): Promise<"done" | "skipped">;
export declare function getAccountId(sts: STS): Promise<string>;
export declare function awsPacker(functionModule: string, options: CommonOptions, wrapperOptions: WrapperOptions, FunctionName: string): Promise<PackerResult>;
export declare function createResponseQueueImpl(state: AwsState, FunctionName: string): Promise<string>;
/**
 * Valid AWS
 * {@link https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html | regions}.
 * Not all of these regions have Lambda support.
 * @public
 */
export declare type AwsRegion = "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "ca-central-1" | "eu-central-1" | "eu-west-1" | "eu-west-2" | "eu-west-3" | "ap-northeast-1" | "ap-northeast-2" | "ap-northeast-3" | "ap-southeast-1" | "ap-southeast-2" | "ap-south-1" | "sa-east-1";
export declare const awsPrice: (pricing: Pricing, ServiceCode: string, filter: {
    [key: string]: string;
}) => Promise<number>;
export declare const requestAwsPrices: (pricing: Pricing, region: AwsRegion) => Promise<AwsPrices>;
export declare function costSnapshot(state: AwsState, stats: FunctionStats): Promise<CostSnapshot>;
export declare const AwsImpl: ProviderImpl<AwsOptions, AwsState>;
