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

import { DispatchChannel } from './DispatchChannel';
import { OutOfBandPayload } from './OutOfBandPayload';

/**
 * The object defining a non-redeemed out-of-band operation as defined 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.
 */
export abstract class PendingOutOfBandOperation {
	/**
	 * The time the out-of-band operation was created (i.e. the time the dispatch
	 * occurred). This can be used by the mobile clients to know which is the latest
	 * operation for the device.
	 */
	abstract creationTimeInEpochMillis: number;

	/**
	 * The name of the dispatcher used by the operation. This provides information
	 * about how the out-of-band operation is transmitted to the mobile device.
	 */
	abstract dispatchChannel: DispatchChannel;

	/**
	 * The {@link OutOfBandPayload} object that can be used with the {@link OutOfBandOperation}
	 * to continue with the operation.
	 */
	abstract payload: OutOfBandPayload;

	/**
	 * Additional information that is not included in the {@link OutOfBandPayload}.
	 * For instance, if this is an operation dispatched using the Firebase dispatcher,
	 * this contains the push notification information in JSON format, as provided
	 * as input of the dispatch request.
	 */
	abstract additionalInformation: string;

	/**
	 * Alternate constructor that creates an {@link PendingOutOfBandOperation} from a json.
	 *
	 * @param json contains the source for instance creation.
	 * @returns a {@link PendingOutOfBandOperation} instance.
	 */
	static fromJson(json: any): PendingOutOfBandOperation {
		return PendingOutOfBandOperationImpl.fromJson(json);
	}
}

export class PendingOutOfBandOperationImpl extends PendingOutOfBandOperation {
	creationTimeInEpochMillis: number;
	dispatchChannel: DispatchChannel;
	payload: OutOfBandPayload;
	additionalInformation: string;

	constructor(
		creationTimeInEpochMillis: number,
		dispatchChannel: DispatchChannel,
		payload: OutOfBandPayload,
		additionalInformation: string
	) {
		super();
		this.creationTimeInEpochMillis = creationTimeInEpochMillis;
		this.dispatchChannel = dispatchChannel;
		this.payload = payload;
		this.additionalInformation = additionalInformation;
	}

	static fromJson(json: any): PendingOutOfBandOperationImpl {
		const payload = OutOfBandPayload.fromJson(json.payload);
		return new PendingOutOfBandOperationImpl(
			json.creationTimeInEpochMillis,
			json.dispatchChannel,
			payload,
			json.additionalInformation
		);
	}
}
