/**
 * Base type for any matcher descriptor
 * @public
 */
export declare interface AnyCaseMatcher {
    '_case:matcher:type': string;
}

/**
 * Any matcher descriptor or data
 * @public
 */
export declare type AnyCaseMatcherOrData = AnyCaseMatcher | AnyData | AnyLeafOrStructure;

/**
 * Helper type to represent any raw json data
 * @public
 */
export declare type AnyData = JsonSerialisablePrimitive | JsonMap | JsonArray;

/**
 * TODO: Remove this type, it doesn't provide much value
 * @internal
 */
export declare type AnyLeafOrStructure = JsonSerialisablePrimitive | JsonOrMatcherArray | JsonOrMatcherMap;

/**
 * Base type for mock descriptors
 * @public
 */
export declare type AnyMockDescriptor = {
    '_case:mock:type': string;
    '_case:run:context:setup': InternalContractCaseCoreSetup;
    request?: AnyCaseMatcher;
    response?: AnyCaseMatcher;
};

/**
 * Union type of all currently known State types.
 * @public
 */
export declare type AnyState = NameOnlyState | StateWithVariables;

/**
 * Union type of all currently known State identifier strings.
 * @public
 */
export declare type AnyStateType = typeof SETUP_NAMED_STATE | typeof SETUP_VARIABLE_STATE;

/**
 * The base SetupInfo provided to all mock setup functions and triggers.
 * @public
 * @remarks
 * All SetupInfo objects extend this type
 */
export declare type BaseSetupInfo = {
    /**
     * Variables provided by state setup functions
     */
    stateVariables: Record<string, VariableValue>;
    /**
     * Setup returned by the mock executor (eg, urls, function names, etc)
     */
    mock: Record<string, VariableValue>;
    /**
     * Arbitrary map of invokeable functions. For most purposes, this can be
     * empty. Useful for allowing plugins to invoke functions - the intention is
     * that arguments and return values are JSON encoded strings.
     */
    functions: Record<string, (...args: string[]) => string>;
};

/**
 * Helper type for extracting a mock descriptor from all the known mock descriptors
 * @public
 * @typeParam KnownMockDescriptors - All the mock descriptor objects known
 * @typeParam T - The string constant for the mock descriptor that we're interested in
 */
export declare type CaseMockDescriptorFor<KnownMockDescriptors extends AnyMockDescriptor, T extends string> = Extract<KnownMockDescriptors, HasTypeForMockDescriptor<T>>;

/**
 * Helper type for a contract case mock descriptor object. All mock descriptors
 * must extend this for the string constant that they use
 * @public
 * @typeParam T - The string constant for the mock descriptor.
 */
export declare interface HasTypeForMockDescriptor<T extends string> {
    '_case:mock:type': T;
}

/**
 * Helper type for extracting state types by their constant
 * @public
 */
export declare type HasTypeForState<T extends AnyStateType> = {
    '_case:state:type': T;
};

/**
 * Describes how contract case behaves with this type of mock.
 * @public
 */
export declare interface InternalContractCaseCoreBehaviour {
    /**
     * The constant type for the mock descriptor used to mock this behaviour
     */
    type: string;
    /**
     * Describes the source of state variables.
     *
     * * `'state'` - variables are provided by state handlers
     * * `'default'` - variables are provided by the default in the state descriptor
     */
    stateVariables: 'state' | 'default';
    /**
     * Describes whether the trigger functions for this mock are user `provided`, or
     * whether ContractCase will use the default functions it `generated`.
     */
    triggers: 'provided' | 'generated';
}

/**
 * Controls the behaviour of the mock when writing or reading contracts with this type.
 *  @public
 */
export declare interface InternalContractCaseCoreSetup {
    /**
     * Defines how the ContractCase core will behave when writing (ie, defining) an Example of this type.
     */
    write: InternalContractCaseCoreBehaviour;
    /**
     * Defines how the ContractCase core will behave when reading (ie, verifying) a Example of this type.
     */
    read: InternalContractCaseCoreBehaviour;
}

/**
 * Determines if a given value is a valid mock descriptor.
 * @public
 * @remarks
 *
 * This function checks if the provided value is an object and contains the
 * property '_case:mock:type', indicating that it is a valid mock descriptor.
 *
 * @param maybeMock - The value to be checked.
 * @returns A boolean indicating whether the provided value is a valid mock descriptor.
 */
export declare const isCaseMock: (maybeMock: unknown) => maybeMock is AnyMockDescriptor;

/**
 * Determines if a specific matcher or data is a lookupable matcher
 * @public
 *
 * @param maybeMatcher - the matcher or data in question
 * @returns true if `maybeMatcher` is a lookupable matcher, false otherwise
 */
export declare const isLookupableMatcher: (maybeMatcher: unknown) => maybeMatcher is LookupableMatcher;

declare type JsonArray = Array<AnyData>;

declare interface JsonMap {
    [key: string]: AnyData;
}

/**
 * Any json array that might contain data or matchers
 * @public
 */
export declare type JsonOrMatcherArray = Array<AnyCaseMatcherOrData>;

/**
 * Any json object that might contain data or matchers
 * @public
 */
export declare type JsonOrMatcherMap = {
    [key: string]: AnyCaseMatcherOrData;
};

declare type JsonSerialisablePrimitive = boolean | number | string | null;

/**
 * The type constant for a lookup matcher
 * @internal
 */
export declare const LOOKUP_MATCHER_TYPE: "_case:Lookup";

/**
 * The matcher descriptor for a lookupable matcher
 *
 * @public
 */
export declare interface LookupableMatcher {
    '_case:matcher:type': typeof LOOKUP_MATCHER_TYPE;
    '_case:matcher:uniqueName': string;
    '_case:matcher:child'?: AnyCaseMatcherOrData;
}

/**
 * Describes a state that only has a name and no other information
 * @public
 */
export declare type NameOnlyState = HasTypeForState<typeof SETUP_NAMED_STATE> & {
    /**
     * The human readable state name, for identifying state handlers.
     * Any string is acceptable, though we recommend keeping state names short.
     *
     * In a future release, some specific state names may be reserved.
     */
    readonly stateName: string;
};

/**
 * Indicates that a matcher should always resolve to this type of value
 * @public
 */
export declare type ResolvesTo<T extends string> = {
    '_case:matcher:resolvesTo': T;
};

/**
 * Type identifier constant for the built-in {@link NameOnlyState} type.
 * @public
 */
export declare const SETUP_NAMED_STATE: "_case:NamedState";

/**
 *  Type identifier constant for the built-in {@link StateWithVariables} type.
 * @public
 */
export declare const SETUP_VARIABLE_STATE: "_case:StateWithVariables";

/**
 * Helper type to extract a specific mock's SetupInfo object form all known SetupInfo objects
 * @public
 * @typeParam AllSetupInfo - All known SetupInfo objects
 * @typeParam T - the type of the mock descriptor that you want to get the SetupInfo for.
 */
export declare type SetupInfoFor<AllSetupInfo, T extends string> = Extract<AllSetupInfo, HasTypeForMockDescriptor<T>> & BaseSetupInfo;

/**
 * Describes a named state that also contains some variables. These variables can be
 * returned by state handlers later.
 * @public
 */
export declare type StateWithVariables = HasTypeForState<typeof SETUP_VARIABLE_STATE> & {
    /**
     * The human readable state name, for identifying state handlers.
     * Any string is acceptable, though we recommend keeping state names short.
     *
     * In a future release, some specific state names may be reserved.
     */
    readonly stateName: string;
    /**
     * Default values and matchers for the variables. The state handler must return
     * a value for each of these named variables. We recommend keeping variables
     * human readable and short. Since the state handler needs to return these, we
     * recommend using similar naming conventions to variables in your chosen
     * language.
     */
    readonly variables: Record<string, AnyCaseMatcherOrData>;
};

declare type VariableValue = any;

export { }
