import { type TopLevelConfig } from '@cloud-copilot/iam-collect';
import { IamCollectClient } from '../collect/client.js';
import { type ClientFactoryPlugin } from '../collect/collect.js';
import { type ResourceType } from '@cloud-copilot/iam-data';
import { type RequestDenial, type RequestGrant } from '@cloud-copilot/iam-simulate';
import { type S3AbacOverride } from '../utils/s3Abac.js';
import { type LightRequestAnalysis } from './requestAnalysis.js';
import { type WorkerBootstrapPlugin } from './WhoCanProcessor.js';
/**
 * Limits the set of principals that `whoCan` tests. The scope is a union of
 * principal ARNs, account IDs, and OU paths. It is **intersected** with the
 * resource-policy-derived scope so that principals outside the resource
 * policy's reach are still excluded.
 */
export interface WhoCanPrincipalScope {
    /** Exact principal ARNs to test individually (does NOT expand to whole-account search). */
    principals?: string[];
    /** Account IDs — test all principals in these accounts. */
    accounts?: string[];
    /** OU paths — test all principals in accounts under these OUs. Each string is a slash-separated path like `o-aaa/r-bbb/ou-ccc`, matching the format used by `aws:PrincipalOrgPaths` and `specificOrganizationalUnits`. */
    ous?: string[];
}
export interface ResourceAccessRequest {
    /**
     * The ARN of the resource to check access for. If not provided, actions must be specified.
     */
    resource?: string;
    /**
     * The account ID the resource belongs to.
     * By default this will be looked up based on the resource ARN, but that may
     * not be possible for all actions, such as wildcard actions like `s3:ListAllMyBuckets`.
     */
    resourceAccount?: string;
    /**
     * The actions to check access for. If not provided, actions will be looked up based on the resource ARN.
     */
    actions: string[];
    /**
     * Whether to sort the results for consistent output.
     */
    sort?: boolean;
    /**
     * An override for S3 ABAC being enabled when checking access to S3 Bucket resources.
     */
    s3AbacOverride?: S3AbacOverride;
    /**
     * The number of worker threads to use for simulations beyond the main thread.
     * If not provided, defaults to number of CPUs - 1.
     */
    workerThreads?: number;
    /**
     * Deny details callback for simulations. If the callback returns true, deny details will be included for that simulation.
     */
    denyDetailsCallback?: (details: LightRequestAnalysis) => boolean;
    /**
     * If true, grant details will be collected for allowed simulations.
     */
    collectGrantDetails?: boolean;
    /**
     * Optional context keys to consider strict when running simulations for this whoCan request.
     * These will be added to the simulation strict context keys used by default.
     */
    strictContextKeys?: string[];
    /**
     * Optional plugin to wrap the collect client with a custom implementation.
     * Used for scenario testing where a layered client needs to be used in worker threads.
     */
    clientFactoryPlugin?: ClientFactoryPlugin;
    /**
     * Optional plugin that runs once per worker thread at startup before any work
     * is processed. Use this for loading instrumentation, initializing logging
     * context, or other worker-lifetime setup.
     */
    workerBootstrapPlugin?: WorkerBootstrapPlugin;
    /**
     * Optional scope to limit the set of principals tested. When provided, the
     * scope is intersected with the resource-policy-derived scope to narrow the
     * search space.
     */
    principalScope?: WhoCanPrincipalScope;
    /**
     * Whether to ignore an existing principal index. This is for testing purposes.
     */
    ignorePrincipalIndex?: boolean;
}
/**
 * Represents a resource pattern that is allowed for a principal, used when wildcards
 * are in the simulation request.
 */
export interface WhoCanAllowedResourcePattern {
    /**
     * The resource pattern that allows access.
     */
    pattern: string;
    /**
     * The resource type for the pattern.
     */
    resourceType: string;
    /**
     * The conditions under which access is allowed for this pattern, if any.
     */
    conditions?: any;
    /**
     * If true, access is only allowed when the session has a specific session name.
     */
    dependsOnSessionName?: boolean;
    /**
     * The policy statements that granted access for this resource pattern.
     */
    details?: RequestGrant[];
}
export interface WhoCanAllowed {
    principal: string;
    service: string;
    action: string;
    level: string;
    /**
     * The conditions under which access is allowed, if any.
     * This will be undefined if access is allowed unconditionally or
     * if `allowedPatterns` are provided.
     */
    conditions?: any;
    /**
     * The resource type for the allowed action. This will be undefined if `allowedPatterns` are provided,
     * since those patterns specify the resource type directly.
     */
    resourceType?: string;
    /**
     * If true, indicates that access is only allowed when the session has a specific session name.
     * This will be false or undefined if `allowedPatterns` are provided, since those patterns would specify the session name condition directly.
     */
    dependsOnSessionName?: boolean;
    /**
     * If there are multiple "allowed" patterns for a single principal because of wildcards
     * in the simulation request, this array will contain the different resource patterns that allow access.
     */
    allowedPatterns?: WhoCanAllowedResourcePattern[];
    /**
     * The policy statements that granted access for this result.
     * Only populated for single resource simulations. For wildcard
     * simulations, see `details` on each entry in `allowedPatterns`.
     */
    details?: RequestGrant[];
}
/**
 * Base type for WhoCanDenyDetails
 */
interface BaseWhoCanDenyDetail {
    /**
     * The principal that was denied
     */
    principal: string;
    /**
     * The service the denied action belongs to
     */
    service: string;
    /**
     * The action that was denied, without the service prefix (e.g. "GetObject" instead of "s3:GetObject")
     */
    action: string;
}
/**
 * Denial details for a single resource request.
 */
export interface SingleWhoCanDenyDetail extends BaseWhoCanDenyDetail {
    type: 'single';
    /**
     * The specific details of why the request was denied
     */
    details: RequestDenial[];
}
/**
 * Denial details for a wildcard resource request that may have matched multiple patterns.
 */
export interface WildcardWhoCanDenyDetail extends BaseWhoCanDenyDetail {
    type: 'wildcard';
    /**
     * The resource patterns that were denied. Could be empty if there
     * were no patterns found that matched the resource for the principal and action.
     *
     * The same pattern can be returned multiple times if there are multiple resource
     * types for that pattern/action combination.
     */
    deniedResources: {
        /**
         * The pattern tested in the simulation that resulted in a denial.
         */
        pattern: string;
        /**
         * The resource type the pattern was tested against.
         */
        resourceType: string;
        /**
         * The specific details of why the request was denied for this pattern.
         */
        details: RequestDenial[];
    }[];
}
/**
 * Details on why a principal was denied access to a resource for a specific action, including the specific patterns that were tested and resulted in denials.
 */
export type WhoCanDenyDetail = SingleWhoCanDenyDetail | WildcardWhoCanDenyDetail;
export interface WhoCanResponse {
    simulationCount: number;
    allowed: WhoCanAllowed[];
    allAccountsChecked: boolean;
    accountsNotFound: string[];
    organizationsNotFound: string[];
    organizationalUnitsNotFound: string[];
    principalsNotFound: string[];
    denyDetails?: WhoCanDenyDetail[] | undefined;
}
/**
 * Processes a single whoCan request by creating a temporary WhoCanProcessor,
 * enqueuing the request, waiting for it to settle, and shutting down. This
 * preserves the original one-shot behavior where workers and cache are created
 * and destroyed per call.
 *
 * For better performance when running multiple requests, use WhoCanProcessor
 * directly to keep workers and cache alive across calls.
 *
 * @param collectConfigs the collect configurations for loading IAM data
 * @param partition the AWS partition (e.g. 'aws', 'aws-cn')
 * @param request the whoCan request parameters
 * @returns the whoCan response with allowed principals and optional deny details
 */
export declare function whoCan(collectConfigs: TopLevelConfig[], partition: string, request: ResourceAccessRequest): Promise<WhoCanResponse>;
export declare function uniqueAccountsToCheck(collectClient: IamCollectClient, accountsToCheck: AccountsToCheck): Promise<{
    accountsNotFound: string[];
    organizationsNotFound: string[];
    organizationalUnitsNotFound: string[];
    accounts: string[];
}>;
export interface AccountsToCheck {
    allAccounts: boolean;
    specificAccounts: string[];
    specificPrincipals: string[];
    specificOrganizations: string[];
    specificOrganizationalUnits: string[];
    checkAnonymous: boolean;
    /**
     * Whether every principal from the resource account should be checked.
     */
    checkAllFromResourceAccount: boolean;
    /**
     * Whether the resource policy explicitly grants access to principals in the
     * resource account. This is true when:
     * - The policy has no narrowing conditions (open wildcard or NotPrincipal), or
     * - The policy conditions explicitly reference the resource account, or
     * - The policy narrows to orgs/OUs (which may include the resource account).
     */
    resourceAccountTrustedByPolicy: boolean;
}
export declare function accountsToCheckBasedOnResourcePolicy(resourcePolicy: any, resourceAccount: string | undefined): Promise<AccountsToCheck>;
export declare function actionsForWhoCan(request: Pick<ResourceAccessRequest, 'actions' | 'resource'>): Promise<string[]>;
/**
 * Get the the possible resource types for an action and resource
 *
 * @param service the service the action belongs to
 * @param action the action to get the resource type for
 * @param resourceArn the resource type matching the action, if any
 * @throws an error if the service or action does not exist, or if the action is a wildcard only action
 */
export declare function lookupActionsForResourceArn(resourceArn: string): Promise<string[]>;
export declare function findResourceTypeForArn(resourceArn: string): Promise<[string, ResourceType]>;
/**
 * Convert a resource pattern from iam-data to a regex pattern
 *
 * @param pattern the pattern to convert to a regex
 * @returns the regex pattern
 */
export declare function convertResourcePatternToRegex(pattern: string): string;
/**
 * Sort the results in a WhoCanResponse in place for consistent output
 *
 * @param whoCanResponse the WhoCanResponse to sort
 */
export declare function sortWhoCanResults(whoCanResponse: WhoCanResponse): void;
export {};
//# sourceMappingURL=whoCan.d.ts.map