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

import { PendingOutOfBandOperationsClockSkewTooBig } from './PendingOutOfBandOperationsClockSkewTooBig';
import { PendingOutOfBandOperationsDeviceProtectionError } from './PendingOutOfBandOperationsDeviceProtectionError';
import type { PendingOutOfBandOperationsError } from './PendingOutOfBandOperationsError';
import { PendingOutOfBandOperationsNetworkError } from './PendingOutOfBandOperationsNetworkError';
import { PendingOutOfBandOperationsNoDeviceLockError } from './PendingOutOfBandOperationsNoDeviceLockError';
import { PendingOutOfBandOperationsOperationNotSupportedByBackendError } from './PendingOutOfBandOperationsOperationNotSupportedByBackendError';
import { PendingOutOfBandOperationsUnknownError } from './PendingOutOfBandOperationsUnknownError';
import { ErrorConverter } from '../../ErrorConverter';

enum PendingOutOfBandOperationsErrorType {
	ClockSkewTooBig,
	DeviceProtectionError,
	NetworkError,
	NoDeviceLockError,
	OperationNotSupportedByBackend,
	Unknown,
}

export class PendingOutOfBandOperationsErrorConverter extends ErrorConverter<PendingOutOfBandOperationsError> {
	convert(): PendingOutOfBandOperationsError {
		const subType =
			PendingOutOfBandOperationsErrorType[
				this.error.type as keyof typeof PendingOutOfBandOperationsErrorType
			];
		switch (subType) {
			case PendingOutOfBandOperationsErrorType.ClockSkewTooBig:
				if (this.error.server) {
					return new PendingOutOfBandOperationsClockSkewTooBig(
						this.error.server,
						this.error.description,
						this.error.cause
					);
				}

				return new PendingOutOfBandOperationsUnknownError(
					this.error.description,
					this.error.cause
				);
			case PendingOutOfBandOperationsErrorType.DeviceProtectionError:
				return new PendingOutOfBandOperationsDeviceProtectionError(
					this.error.description,
					this.error.cause
				);
			case PendingOutOfBandOperationsErrorType.NetworkError:
				if (this.error.server) {
					return new PendingOutOfBandOperationsNetworkError(
						this.error.server,
						this.error.description,
						this.error.cause
					);
				}

				return new PendingOutOfBandOperationsUnknownError(
					this.error.description,
					this.error.cause
				);
			case PendingOutOfBandOperationsErrorType.NoDeviceLockError:
				return new PendingOutOfBandOperationsNoDeviceLockError(
					this.error.description,
					this.error.cause
				);
			case PendingOutOfBandOperationsErrorType.OperationNotSupportedByBackend:
				if (this.error.server) {
					return new PendingOutOfBandOperationsOperationNotSupportedByBackendError(
						this.error.server,
						this.error.description,
						this.error.cause
					);
				}

				return new PendingOutOfBandOperationsUnknownError(
					this.error.description,
					this.error.cause
				);
			case PendingOutOfBandOperationsErrorType.Unknown:
				return new PendingOutOfBandOperationsUnknownError(
					this.error.description,
					this.error.cause,
					this.error.server
				);
		}
	}
}
