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

import { DeviceInformationMismatch } from './DeviceInformationMismatch';
import type { DeviceInformationCheckError } from '../../error/deviceInformation/check/DeviceInformationCheckError';
import { DeviceInformationCheckErrorConverter } from '../../error/deviceInformation/check/DeviceInformationCheckErrorConverter';

/**
 * This is the result of the {@link DeviceInformationCheck} operation.
 *
 * If configuration mismatches in a given server could be found, but retrieving the server
 * configuration failed for another server. The found mismatches will be returned by the
 * {@link mismatches} property, and the error will be returned by the {@link errors} property.
 *
 * @see {@link DeviceInformationCheck}
 */
export abstract class DeviceInformationCheckResult {
	/**
	 * Returns the mismatches configuration mismatches between the mobile SDK.
	 *
	 * **WARNING** \
	 * If your application has been upgraded from versions of the SDK previous to 3.8.0, and thus
	 * some users were registered using earlier versions, some false positive {@link MissingAuthenticatorInServer}
	 * mismatches can be returned for those users.
	 */
	abstract mismatches: Array<DeviceInformationMismatch>;

	/**
	 * Returns the errors that occurred retrieving the configuration mismatches.
	 *
	 * @return the errors that occurred retrieving the configuration mismatches.
	 */
	abstract errors: Array<DeviceInformationCheckError>;

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

export class DeviceInformationCheckResultImpl extends DeviceInformationCheckResult {
	mismatches: Array<DeviceInformationMismatch>;
	errors: Array<DeviceInformationCheckError>;

	constructor(
		mismatches: Array<DeviceInformationMismatch>,
		errors: Array<DeviceInformationCheckError>
	) {
		super();
		this.mismatches = mismatches;
		this.errors = errors;
	}

	static fromJson(json: any): DeviceInformationCheckResultImpl {
		const mismatchesData = json.mismatches;
		const errorsData = json.errors;
		const mismatches = mismatchesData?.map(DeviceInformationMismatch.fromJson);
		const errors = errorsData?.map((error: any) =>
			new DeviceInformationCheckErrorConverter(error).convert()
		);
		return new DeviceInformationCheckResultImpl(mismatches || [], errors || []);
	}
}
