import "./../../shared/global";
import { Client, IFetchResponse, IResult, IResultList, IManagedObject, IUser, IApplication, IAlarm, IEvent, Paging, IApplicationVersion, IAuditRecord, IOperation, IOperationBulk, IDeviceRegistration, IExternalIdentity, IManagedObjectBinary, IMeasurement, ITenant, ITenantOption, ITenantLoginOption, IUserReference, IUserGroup, IRole, IRoleReference, IIdentified } from "@c8y/client";
import { C8yClientOptions } from "../../shared/c8yclient";
import "../pact/c8ymatch";
declare global {
    namespace Cypress {
        interface Chainable {
            /**
             * Create a c8y/client `Client` to interact with Cumulocity API. Yielded
             * results are `Cypress.Response` objects as returned by `cy.request`.
             *
             * `cy.c8yclient` supports c8y/client `BasicAuth`, `CookieAuth` and `BearerAuth`.
             *
             * If auth is not passed explicitly using `cy.getAuth()`, `cy.useAuth()` or
             * `cy.login()`, the following behavior will be applied:
             * 1. Use Basic auth if preferBasicAuth=true option is set and username/password are present.
             * 2. Use Cookie auth if authorization and X-XSRF-TOKEN cookies are present.
             * 3. Use Bearer auth from `C8Y_TOKEN` env variable.
             * 4. Use Basic auth from `C8Y_USERNAME` and `C8Y_PASSWORD` env variable.
             *
             * For CookieAuth you should call `cy.login()` before using `cy.c8yclient` to
             * create the the required cookies. To force using basic auth method, pass
             * credentials via `cy.getAuth().c8yclient()` or use `preferBasicAuth` option.
             *
             * `cy.c8yclient` supports chaining of requests. By chaining the response of
             * one request will be provided as second argument to the next request.
             *
             * Using the `options` argument it is possible to overwrite the default
             * behavior or configure `cy.c8yclient`.
             *
             * @example
             * cy.getAuth("admin")
             *   .c8yclient().then((c) => {
             *     Cypress.env("C8Y_TENANT", c.core.tenant);
             * });
             *
             * cy.c8yclient((c) => c.user.delete(newuser.username), {
             *   failOnStatusCode: false,
             * }).then((deleteResponse) => {
             *   expect(deleteResponse.status).to.be.oneOf([204, 404]);
             * });
             *
             * cy.c8yclient([
             *   (c) =>
             *     c.core.fetch(
             *       "/user/" + c.core.tenant + "/groupByName/" + permission
             *     ),
             *   (c, groupResponse) =>
             *     c.userGroup.addUserToGroup(groupResponse.body.id, userId),
             *   ]);
             * });
             *
             * cy.c8yclient((c) =>
             *   c.core.fetch("/user/" + c.core.tenant + "/groupByName/" + permission)
             * ).c8yclient((c, groupResponse) =>
             *   c.userGroup.addUserToGroup(groupResponse.body.id, userId),
             * );
             */
            c8yclient<T = any, R = any>(serviceFn: C8yClientServiceFn<R, T> | C8yClientServiceFn<R, any>[], options?: C8yClientOptions): Chainable<Response<T>>;
            c8yclient<T = any, R = any>(serviceFn: C8yClientServiceArrayFn<R, T> | C8yClientServiceArrayFn<R, any>[], options?: C8yClientOptions): Chainable<Response<T>[]>;
            c8yclient<T = any, R = any>(serviceFn: C8yClientServiceListFn<R, T>, options?: C8yClientOptions): Chainable<Response<C8yCollectionResponse<T>>>;
            c8yclient(): Chainable<Client>;
            /**
             * Convenience for cy.c8yclient with failOnStatus false. Use if the request is
             * expected to fail.
             *
             * @see c8yclient
             */
            c8yclientf<T = any, R = any>(serviceFn: C8yClientServiceFn<R, T> | C8yClientServiceFn<R, any>[], options?: C8yClientOptions): Chainable<Response<T>>;
            c8yclientf<T = any, R = any>(serviceFn: C8yClientServiceArrayFn<R, T> | C8yClientServiceArrayFn<R, any>[], options?: C8yClientOptions): Chainable<Response<T>[]>;
            c8yclientf<T = any, R = any>(serviceFn: C8yClientServiceListFn<R, T>, options?: C8yClientOptions): Chainable<Response<C8yCollectionResponse<T>>>;
        }
    }
    type C8yClientIResult<T> = IResult<T> | IResult<null> | IFetchResponse | null | void;
    type C8yClientServiceFn<R, T> = (client: Client, previousResponse: Cypress.Response<R>) => Promise<C8yClientIResult<T>>;
    type C8yClientServiceArrayFn<R, T> = (client: Client, previousResponse: Cypress.Response<R>) => Promise<C8yClientIResult<T>>[];
    type C8yClientServiceListFn<R, T> = (client: Client, previousResponse: Cypress.Response<R>) => Promise<IResultList<T>>;
    type C8yClientFnArg<R = any, T = any> = C8yClientServiceFn<R, T> | C8yClientServiceArrayFn<R, T>[] | C8yClientServiceListFn<R, T>;
    class C8yClientError extends Error {
        originalError?: Error;
        constructor(message: string, originalError?: Error);
    }
    type C8yCollectionResponse<T> = T extends IAlarm ? {
        alarms: T[];
    } & CollectionMetadata<T> : T extends IManagedObject ? {
        managedObjects: T[];
    } & CollectionMetadata<T> : T extends IEvent ? {
        events: T[];
    } & CollectionMetadata<T> : T extends IOperation ? {
        operations: T[];
    } & CollectionMetadata<T> : T extends IMeasurement ? {
        measurements: T[];
    } & CollectionMetadata<T> : T extends IAuditRecord ? {
        auditRecords: T[];
    } & CollectionMetadata<T> : T extends IDeviceRegistration ? {
        newDeviceRequests: T[];
    } & CollectionMetadata<T> : T extends IExternalIdentity ? {
        externalIds: T[];
    } & CollectionMetadata<T> : T extends IOperationBulk ? {
        bulkOperations: T[];
    } & CollectionMetadata<T> : T extends IManagedObjectBinary ? {
        managedObjects: T[];
    } & CollectionMetadata<T> : T extends IApplicationVersion ? {
        versions: T[];
    } & CollectionMetadata<T> : T extends IRoleReference ? {
        references: T[];
    } & CollectionMetadata<T> : T extends ITenantLoginOption ? {
        loginOptions: T[];
    } & CollectionMetadata<T> : T extends ITenantOption ? {
        options: T[];
    } & CollectionMetadata<T> : T extends IUserReference ? {
        references: T[];
    } & CollectionMetadata<T> : T extends IUserGroup ? {
        groups: T[];
    } & CollectionMetadata<T> : T extends IUser | IRole | IApplication | ITenant | IIdentified ? CustomFragmentsInterfaceResponse<T> : never;
    type CollectionMetadata<T> = {
        statistics?: Paging<T>;
        self?: string;
        next?: string;
        prev?: string;
    };
    type CustomFragmentsInterfaceResponse<T> = {
        applications?: T[];
        roles?: T[];
        tenants?: T[];
        users?: T[];
    } & CollectionMetadata<T>;
}
export declare const defaultClientOptions: () => C8yClientOptions;
/**
 * Checks if the given object is an array only containing functions.
 * @param obj The object to check.
 */
export declare function isArrayOfFunctions(functions: C8yClientFnArg | C8yClientServiceArrayFn<any, any>[] | C8yClientServiceFn<any, any>[]): functions is C8yClientServiceArrayFn<any, any>[] | C8yClientServiceFn<any, any>[];
