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

import { PendingOutOfBandOperation } from './PendingOutOfBandOperation';
import type { PendingOutOfBandOperationsError } from '../../error/outOfBand/pendingOutOfBandOperationsError/PendingOutOfBandOperationsError';
import { PendingOutOfBandOperationsErrorConverter } from '../../error/outOfBand/pendingOutOfBandOperationsError/PendingOutOfBandOperationsErrorConverter';

/**
 * The object with the non-redeemed out-of-band operations returned by nevisFIDO
 * in the {@link https://docs.nevis.net/nevisfido/reference-guide/uaf-http-api/device-service#get-device-out-of-band-operations | Get Device Out-of-Band Operations}
 * service.
 *
 * If the pending operations in a given server could be found, but they failed
 * for another server. The found operations will be returned by the {@link operations}
 * method, and the error will be returned by the {@link errors} method.
 */
export abstract class PendingOutOfBandOperationsResult {
	/**
	 * Returns the out-of-band operations of the device that have not been redeemed,
	 * nor timed-out.
	 */
	abstract operations: Array<PendingOutOfBandOperation>;

	/**
	 * Returns the errors that occurred retrieving the pending out-of-band operations.
	 */
	abstract errors: Array<PendingOutOfBandOperationsError>;

	/**
	 * Alternate constructor that creates a {@link PendingOutOfBandOperationsResult} from a json.
	 *
	 * @returns the created {@link PendingOutOfBandOperationsResult} instance.
	 */
	static fromJson(json: any): PendingOutOfBandOperationsResult {
		return PendingOutOfBandOperationsResultImpl.fromJson(json);
	}
}

export class PendingOutOfBandOperationsResultImpl extends PendingOutOfBandOperationsResult {
	operations: Array<PendingOutOfBandOperation>;
	errors: Array<PendingOutOfBandOperationsError>;

	constructor(
		operations: Array<PendingOutOfBandOperation>,
		errors: Array<PendingOutOfBandOperationsError>
	) {
		super();
		this.operations = operations;
		this.errors = errors;
	}

	static fromJson(json: any): PendingOutOfBandOperationsResultImpl {
		const operationsData = json.operations;
		const errorsData = json.errors;
		const operations = operationsData?.map((operation: any) =>
			PendingOutOfBandOperation.fromJson(operation)
		);
		const errors = errorsData?.map((error: any) =>
			new PendingOutOfBandOperationsErrorConverter(error).convert()
		);
		return new PendingOutOfBandOperationsResultImpl(operations || [], errors || []);
	}
}
