import { IUser, IApplication, ICurrentTenant, IDeviceCredentials, IUserGroup } from "@c8y/client";
import { C8yAuthOptions } from "../../shared/auth";
import { C8yClientOptions } from "../../shared/c8yclient";
import { DeleteOptions, DeleteUserInput } from "../../shared/c8yclient/";
declare global {
    namespace Cypress {
        interface Chainable {
            /**
             * Create a new user in Cumulocity. Assigns requested roles and subcribes to
             * applications with given names.
             *
             * Uses cy.c8yclient internally. Will fail if user already exists.
             *
             * Pass auth if required or call `cy.login()` before to use `XSRF-TOKEN`cookie for
             * authentication.
             *
             * @example
             * cy.createUser({
             *   userName: "newuser",
             *   password: "newpassword",
             *   email: "newuser@example.com",
             *   displayName: "New User",
             * });
             *
             * @param {C8yAuthOptions} authOptions the C8yAuthOptions authentication options including username and password
             * @param {string | IUser} userOptions the user name or IUser options defining the user to be created
             * @param {string[]} roles the roles to be assigned to the user
             * @param {string[] | IApplication[]} applications the name of applications or IApplication objects to subscribe the user to
             * @param {C8yClientOptions} c8yoptions the C8yClientOptions options passed to cy.c8yclient
             *
             * @returns {[C8yAuthOptions, string]} the auth options and id of the user created for chaining
             */
            createUser(...args: [
                authOptions: C8yAuthOptions,
                userOptions: string | IUser,
                roles?: string[],
                applications?: string[] | IApplication[],
                c8yoptions?: C8yClientOptions
            ] | [
                userOptions: string | IUser,
                roles?: string[],
                applications?: string[] | IApplication[],
                c8yoptions?: C8yClientOptions
            ]): Chainable<Cypress.Response<IUser>>;
            /**
             * Delete a user from Cumulocity. Will automatically deal with response status codes
             * to check if the user was deleted or did not exist. Will return success in both cases.
             *
             * Pass auth if required or call `cy.login()` before to use `XSRF-TOKEN`cookie for
             * authentication.
             *
             * @example
             * cy.deleteUser("myuser");
             * cy.deleteUser(["myuser1", "myuser2"]);
             * cy.deleteUser({ userName: "myuser", displayName: "My User" });
             * cy.deleteUser((user) => user.email === "myuser@example.com");
             *
             * cy.getAuth("admin").deleteUser("myuser");
             *
             * @param {C8yAuthOptions} authOptions the C8yAuthOptions authentication options including username and password
             * @param {DeleteUserInput} username the id or username as string, an IUser object, or a predicate function to identify the user(s) to be deleted
             * @param {C8yClientOptions & DeleteUserOptions} c8yoptions the C8yClientOptions options passed to cy.c8yclient
             * @param {boolean} c8yoptions.ignoreNotFound whether to ignore not found users (default: true)
             *
             * @returns {C8yAuthOptions} the authentication options for chaining to allow further commands
             */
            deleteUser(...args: [
                username: DeleteUserInput,
                c8yoptions?: C8yClientOptions & DeleteOptions
            ] | [
                authOptions: C8yAuthOptions,
                username: DeleteUserInput,
                c8yoptions?: C8yClientOptions & DeleteOptions
            ]): Chainable<C8yAuthOptions>;
            /**
             * Creates a global role in Cumulocity with specified permissions.
             *
             * This command creates a new global role with the provided name and description,
             * then assigns the specified permissions to it.
             *
             * @example
             * cy.createGlobalRole(
             *   { name: "DeviceManager", description: "Can manage all devices" },
             *   ["ROLE_INVENTORY_READ", "ROLE_INVENTORY_ADMIN", "ROLE_IDENTITY_READ"]
             * );
             *
             * @example
             * cy.getAuth("admin").createGlobalRole(
             *   { name: "ReportViewer", description: "Access to view reports" },
             *   ["ROLE_REPORT_READ"]
             * );
             *
             * @param {C8yAuthOptions} authOptions - Authentication options including username and password
             * @param {{ name: string, description?: string }} roleOptions - The name and optional description for the global role
             * @param {string[]} roles - Array of role permissions to assign to the global role
             * @param {C8yClientOptions} c8yoptions - Options passed to cy.c8yclient
             *
             * @returns {Chainable<IUserGroup>} The created global role for chaining
             */
            createGlobalRole(...args: [
                roleOptions: string | {
                    name: string;
                    description?: string;
                },
                roles: string[],
                c8yoptions?: C8yClientOptions
            ] | [
                authOptions: C8yAuthOptions,
                roleOptions: string | {
                    name: string;
                    description?: string;
                },
                roles: string[],
                c8yoptions?: C8yClientOptions
            ]): Chainable<Cypress.Response<IUserGroup>>;
            /**
             * Deletes global roles from Cumulocity by name.
             *
             * This command retrieves all global roles, filters those matching the provided names,
             * and then deletes them. Will not fail if a role does not exist.
             *
             * @example
             * cy.deleteGlobalRoles(["DeviceManager", "ReportViewer"]);
             *
             * @example
             * cy.getAuth("admin").deleteGlobalRoles(["AdminRole", "UserRole"]);
             *
             * @param {C8yAuthOptions} authOptions - Authentication options including username and password
             * @param {string[]} roleNames - Array of role names to delete
             * @param {C8yClientOptions & DeleteOptions} c8yoptions the C8yClientOptions options passed to cy.c8yclient
             * @param {boolean} c8yoptions.ignoreNotFound whether to ignore not found global roles (default: true)
             *
             * @returns {Chainable<C8yAuthOptions>} The auth options for chaining
             */
            deleteGlobalRoles(...args: [roleNames: string[], c8yoptions?: C8yClientOptions & DeleteOptions] | [
                authOptions: C8yAuthOptions,
                roleNames: string[],
                c8yoptions?: C8yClientOptions & DeleteOptions
            ]): Chainable<C8yAuthOptions>;
            /**
             * Assign roles to a user.
             *
             * Pass auth if required or call `cy.login()` before to use `XSRF-TOKEN`cookie for
             * authentication.
             *
             * @example
             * cy.assignUserRoles("user", ["role1", "role2"]);
             *
             * @param {C8yAuthOptions} authOptions the C8yAuthOptions authentication options including username and password
             * @param {string} username the name of the user to be deleted
             * @param {string[]} roles the roles to be assigned to the user
             * @param {C8yClientOptions} c8yoptions the C8yClientOptions options passed to cy.c8yclient
             *
             * @returns {C8yAuthOptions} the auth options for chaining
             */
            assignUserRoles(...args: [
                username: string | IUser,
                roles: string[],
                c8yoptions?: C8yClientOptions
            ] | [
                authOptions: C8yAuthOptions,
                username: string | IUser,
                roles: string[],
                c8yoptions?: C8yClientOptions
            ]): Chainable<C8yAuthOptions>;
            /**
             * Clear all roles currently assigned to a user.
             *
             * Pass auth if required or call `cy.login()` before to use `XSRF-TOKEN`cookie for
             * authentication.
             *
             * @example
             * cy.clearUserRoles("user");
             *
             * @param {C8yAuthOptions} authOptions the C8yAuthOptions authentication options including username and password
             * @param {string} username the name of the user to be deleted
             * @param {C8yClientOptions} c8yoptions the C8yClientOptions options passed to cy.c8yclient
             *
             * @returns {C8yAuthOptions} the auth options for chaining
             */
            clearUserRoles(...args: [username: string | IUser, c8yoptions?: C8yClientOptions] | [
                authOptions: C8yAuthOptions,
                username: string | IUser,
                c8yoptions?: C8yClientOptions
            ]): Chainable<C8yAuthOptions>;
            /**
             * Gets information about the current tenant.
             *
             * If no authentication session cookie is used.
             *
             * @example
             * cy.getCurrentTenant();
             * cy.getAuth("admin").getCurrentTenant();
             *
             * @param {C8yAuthOptions} authOptions the C8yAuthOptions authentication options including username and password
             * @param {C8yClientOptions} c8yoptions the C8yClientOptions options passed to cy.c8yclient
             */
            getCurrentTenant(authOptions?: C8yAuthOptions, c8yoptions?: C8yClientOptions): Chainable<Cypress.Response<ICurrentTenant>>;
            /**
             * Convenience getter for name of the current tenant.
             *
             * If no authentication session cookie is used.
             *
             * Tenant id is stored in C8Y_TENANT environment variable. C8Y_TENANT is used
             * internally and checked before quering current tenant for it's id.
             *
             * @example
             * cy.getTenantId();
             * cy.getAuth("admin").getTenantId();
             *
             * @param {C8yAuthOptions} options - The authentication options including username and password
             * @returns {Chainable<string>}
             */
            getTenantId(authOptions?: C8yAuthOptions): Chainable<string>;
            /**
             * Get Cumulocity system version. System version is loaded from `/tenant/system/options` endpoint.
             *
             * The system version is stored automatically in `C8Y_SYSTEM_VERSION` environment variable. If
             * the `C8Y_SYSTEM_VERSION` is set, the value is returned from the environment variable without requesting
             * the system version from the backend.
             *
             * @example
             * cy.getSystemVersion();
             * cy.log(Cypress.env("C8Y_SYSTEM_VERSION"));
             *
             * cy.getAuth("admin").getSystemVersion().then((version) => {
             *  cy.log(version);
             * });
             *
             * @param {C8yAuthOptions} options - The authentication options including username and password
             * @param {C8yClientOptions} clientOptions - The options passed to c8yclient for loading the version
             * @returns {Chainable<string>} The system version of Cumulocity backend
             */
            getSystemVersion(authOptions?: C8yAuthOptions, clientOptions?: C8yClientOptions): Chainable<string | undefined>;
            /**
             * Get Cumulocity shell version. The shell version is differrent to the system version and defining
             * the UI application being used as shell in the application tested. This is typically `cockpit`,
             * `devicemanagement` or `administration`. The shell version is loaded from
             * `/apps/{shellName}/cumulocity.json`.
             *
             * Shell name can be set as `C8Y_SHELL_NAME` environment variable. If no shell name is provided
             * `cockpit` is used as default.
             *
             * The shell version is stored automatically in `C8Y_SHELL_VERSION` environment variable. If
             * `C8Y_SHELL_VERSION` is set, the value is returned from the environment variable without requesting
             * the shell version from the backend.
             *
             * @example
             * cy.getShellVersion("cockpit").then((version) => {
             *   cy.log(version);
             * });
             *
             * cy.getAuth("admin").getShellVersion("cockpit");
             * cy.log(Cypress.env("C8Y_SHELL_VERSION"));
             *
             * @param {C8yAuthOptions} options - The authentication options including username and password
             * @param {string} shellName - The name of the shell to get the version for
             * @param {C8yClientOptions} clientOptions - The options passed to c8yclient for loading the version
             * @returns {Chainable<string>} The shekk
             */
            getShellVersion(...args: [shellName?: string, clientOptions?: C8yClientOptions] | [
                authOptions?: C8yAuthOptions,
                shellName?: string,
                clientOptions?: C8yClientOptions
            ]): Chainable<string | undefined>;
            /**
             * Bootstrap device credentials. Doing the same as c.deviceRegistration.bootstrap(), but works
             * with getAuth(). Requires bootstrap credentials to be passed via getAuth().
             *
             * @example
             * cy.getAuth("devicebootstrap")
             *   .bootstrapDeviceCredentials(id)
             *   .useAuth()
             *
             * @param {C8yAuthOptions} options - The authentication options including username and password
             * @returns {Chainable<IDeviceCredentials | undefined>}
             */
            bootstrapDeviceCredentials(...args: [id: string | IUser, c8yoptions?: C8yClientOptions] | [
                authOptions: C8yAuthOptions,
                id: string,
                c8yoptions?: C8yClientOptions
            ]): Chainable<IDeviceCredentials>;
        }
    }
}
