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

import { TypedData } from './TypedData';
import { Account } from '../../localData/Account';
import { IdUserNamePair } from '../../localData/IdUserNamePair';
import { Server } from '../../localData/Server';
import {
	DeviceInformationMismatch,
	DeviceNameMismatch,
	FcmRegistrationTokenMismatch,
	MissingAuthenticatorInMobileDevice,
	MissingAuthenticatorInServer,
	MissingDeviceInformationInMobileDevice,
	MissingDeviceInformationInServer,
} from '../../operations/deviceInformation/DeviceInformationMismatch';

class DeviceInformationMismatchData {
	keyId?: string;
	aaid?: string;
	dispatchTargetId?: string;
	nameInServer?: string;
	nameInMobileDevice?: string;
	fcmRegistrationTokenInServer?: string;
	fcmRegistrationTokenInMobileDevice?: string;
	idUsernamePair?: IdUserNamePair;
	account?: Account;
	server?: Server;
}

export abstract class TypedDeviceInformationMismatch extends TypedData<DeviceInformationMismatchData> {
	abstract data: DeviceInformationMismatchData;

	static create(mismatch: DeviceInformationMismatch): TypedDeviceInformationMismatch {
		if (mismatch instanceof MissingAuthenticatorInMobileDevice) {
			return new TypedMissingAuthenticatorInMobileDevice(mismatch);
		} else if (mismatch instanceof MissingAuthenticatorInServer) {
			return new TypedMissingAuthenticatorInServer(mismatch);
		} else if (mismatch instanceof MissingDeviceInformationInMobileDevice) {
			return new TypedMissingDeviceInformationInMobileDevice(mismatch);
		} else if (mismatch instanceof MissingDeviceInformationInServer) {
			return new TypedMissingDeviceInformationInServer(mismatch);
		} else if (mismatch instanceof DeviceNameMismatch) {
			return new TypedDeviceNameMismatch(mismatch);
		} else if (mismatch instanceof FcmRegistrationTokenMismatch) {
			return new TypedFcmRegistrationTokenMismatch(mismatch);
		} else {
			throw new Error(`Unknown device information mismatch (${mismatch.constructor.name}).`);
		}
	}
}

export class TypedMissingAuthenticatorInMobileDevice extends TypedDeviceInformationMismatch {
	type = 'MissingAuthenticatorInMobileDevice';
	data: DeviceInformationMismatchData;

	constructor(wrapped: MissingAuthenticatorInMobileDevice) {
		super();
		this.data = new DeviceInformationMismatchData();
		this.data.keyId = wrapped.keyId;
		this.data.aaid = wrapped.aaid;
		this.data.server = wrapped.server;
	}
}

export class TypedMissingAuthenticatorInServer extends TypedDeviceInformationMismatch {
	type = 'MissingAuthenticatorInServer';
	data: DeviceInformationMismatchData;

	constructor(wrapped: MissingAuthenticatorInServer) {
		super();
		this.data = new DeviceInformationMismatchData();
		this.data.keyId = wrapped.keyId;
		this.data.account = wrapped.account;
		this.data.aaid = wrapped.aaid;
	}
}

export class TypedMissingDeviceInformationInMobileDevice extends TypedDeviceInformationMismatch {
	type = 'MissingDeviceInformationInMobileDevice';
	data: DeviceInformationMismatchData;

	constructor(wrapped: MissingDeviceInformationInMobileDevice) {
		super();
		this.data = new DeviceInformationMismatchData();
		this.data.dispatchTargetId = wrapped.dispatchTargetId;
		this.data.server = wrapped.server;
	}
}

export class TypedMissingDeviceInformationInServer extends TypedDeviceInformationMismatch {
	type = 'MissingDeviceInformationInServer';
	data: DeviceInformationMismatchData;

	constructor(wrapped: MissingDeviceInformationInServer) {
		super();
		this.data = new DeviceInformationMismatchData();
		this.data.idUsernamePair = wrapped.idUsernamePair;
		this.data.server = wrapped.server;
	}
}

export class TypedDeviceNameMismatch extends TypedDeviceInformationMismatch {
	type = 'DeviceNameMismatch';
	data: DeviceInformationMismatchData;

	constructor(wrapped: DeviceNameMismatch) {
		super();
		this.data = new DeviceInformationMismatchData();
		this.data.nameInServer = wrapped.nameInServer;
		this.data.nameInMobileDevice = wrapped.nameInMobileDevice;
		this.data.server = wrapped.server;
	}
}

export class TypedFcmRegistrationTokenMismatch extends TypedDeviceInformationMismatch {
	type = 'FcmRegistrationTokenMismatch';
	data: DeviceInformationMismatchData;

	constructor(wrapped: FcmRegistrationTokenMismatch) {
		super();
		this.data = new DeviceInformationMismatchData();
		this.data.fcmRegistrationTokenInServer = wrapped.fcmRegistrationTokenInServer;
		this.data.fcmRegistrationTokenInMobileDevice = wrapped.fcmRegistrationTokenInMobileDevice;
		this.data.server = wrapped.server;
	}
}
