/**
 * Copyright © 2023-2024 Nevis Security AG. All rights reserved.
 */

import {
	type AuthCloudApiRegistration,
	AuthCloudApiRegistrationImpl,
} from './AuthCloudApiRegistration';
import { type Authentication, AuthenticationImpl } from './Authentication';
import { type Deregistration, DeregistrationImpl } from './Deregistration';
import {
	type DeviceInformationCheck,
	DeviceInformationCheckImpl,
} from './deviceInformation/DeviceInformationCheck';
import {
	type DeviceInformationSync,
	DeviceInformationSyncImpl,
} from './deviceInformation/DeviceInformationSync';
import {
	type DeviceInformationChange,
	DeviceInformationChangeImpl,
} from './DeviceInformationChange';
import { type OutOfBandOperation, OutOfBandOperationImpl } from './outOfBand/OutOfBandOperation';
import {
	type OutOfBandPayloadDecode,
	OutOfBandPayloadDecodeImpl,
} from './outOfBand/OutOfBandPayloadDecode';
import {
	type PendingOutOfBandOperations,
	PendingOutOfBandOperationsImpl,
} from './outOfBand/PendingOutOfBandOperations';
import { type PasswordChange, PasswordChangeImpl } from './password/PasswordChange';
import { type PinChange, PinChangeImpl } from './pin/PinChange';
import { type Registration, RegistrationImpl } from './Registration';

/**
 * The interface used to obtain operation objects (registration, deregistration, authentication...).
 *
 * @see {@link MobileAuthenticationClient.operations}
 */
export abstract class Operations {
	/**
	 * Returns an {@link OutOfBandOperation} object.
	 *
	 * The object can be used to process an {@link OutOfBandPayload} that was obtained from a QR code or
	 * an Intent (push message for example).
	 */
	abstract outOfBandOperation: OutOfBandOperation;
	/**
	 * Returns an {@link OutOfBandPayloadDecode} object.
	 *
	 * The object can be used to decode an {@link OutOfBandPayload} from a String in JSON format.
	 */
	abstract outOfBandPayloadDecode: OutOfBandPayloadDecode;

	/**
	 * Returns a {@link Registration} object.
	 *
	 * The object can be used to register a new authenticator.
	 */
	abstract registration: Registration;

	/**
	 * Returns an {@link AuthCloudApiRegistration} object.
	 *
	 * The object can be used to register a new authenticator when using the Nevis Auth Cloud
	 * enroll API.
	 */
	abstract authCloudApiRegistration: AuthCloudApiRegistration;

	/**
	 * Returns an {@link Authentication} object.
	 *
	 * The object can be used to authenticate using an already registered authenticator.
	 */
	abstract authentication: Authentication;

	/**
	 * Returns a {@link Deregistration} object.
	 *
	 * The object can be used to deregister authenticators.
	 */
	abstract deregistration: Deregistration;

	/**
	 * Returns a {@link DeviceInformationChange} object.
	 *
	 * The object can be used to update the device information.
	 */
	abstract deviceInformationChange: DeviceInformationChange;

	/**
	 * Returns a {@link DeviceInformationCheck} object.
	 *
	 * This operation allows identifying possible configuration mismatches between the server and
	 * the application running the Mobile SDK.
	 *
	 * This is supported only when the backend uses nevisFIDO 7.2408.** or later.
	 */
	abstract deviceInformationCheck: DeviceInformationCheck;

	/**
	 * Returns a {@link DeviceInformationSync} object.
	 *
	 * This operation allows correcting the configuration mismatches between the server and the
	 * application running the Mobile SDK that were found with a {@link DeviceInformationCheck} operation.
	 *
	 * This is supported only when the backend uses nevisFIDO 7.2408.** or later.
	 */
	abstract deviceInformationSync: DeviceInformationSync;

	/**
	 * Returns a {@link PendingOutOfBandOperations} object.
	 *
	 * This operation retrieves the out-of-band operations that have been started
	 * in the server, and must be handled by the application running the Mobile SDK.
	 *
	 * This is supported only when the backend uses nevisFIDO 7.2402.** or later.
	 *
	 */
	abstract pendingOutOfBandOperations: PendingOutOfBandOperations;

	/**
	 * Returns a {@link PinChange} object.
	 *
	 * The object can be used to change the PIN of a registered PIN authenticator.
	 */
	abstract pinChange: PinChange;

	/**
	 * Returns a {@link PasswordChange} object.
	 *
	 * The object can be used to change the password of a registered password authenticator.
	 */
	abstract passwordChange: PasswordChange;
}

export class OperationsImpl extends Operations {
	outOfBandOperation: OutOfBandOperation = new OutOfBandOperationImpl();
	outOfBandPayloadDecode: OutOfBandPayloadDecode = new OutOfBandPayloadDecodeImpl();
	registration: Registration = new RegistrationImpl();
	authCloudApiRegistration: AuthCloudApiRegistration = new AuthCloudApiRegistrationImpl();
	authentication: Authentication = new AuthenticationImpl();
	deregistration: Deregistration = new DeregistrationImpl();
	deviceInformationChange: DeviceInformationChange = new DeviceInformationChangeImpl();
	deviceInformationCheck: DeviceInformationCheck = new DeviceInformationCheckImpl();
	deviceInformationSync: DeviceInformationSync = new DeviceInformationSyncImpl();
	pendingOutOfBandOperations: PendingOutOfBandOperations = new PendingOutOfBandOperationsImpl();
	pinChange: PinChange = new PinChangeImpl();
	passwordChange: PasswordChange = new PasswordChangeImpl();
}
