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

import NevisMobileAuthentication

extension OutOfBandRegistration {
	func configure(by outOfBandRegistrationMessage: OutOfBandRegistrationMessage, operation outOfBandRegistrationOperation: OutOfBandRegistrationOperation) async -> OutOfBandRegistration {
		if let deviceInformation = outOfBandRegistrationMessage.deviceInformation {
			self.deviceInformation(deviceInformation)
		}

		if let allowDevicePasscodeAsFallback = outOfBandRegistrationMessage.allowDevicePasscodeAsFallback {
			self.allowDevicePasscodeAsFallback(allowDevicePasscodeAsFallback)
		}

		if let invalidateOnNewOsBiometrics = outOfBandRegistrationMessage.invalidateOnNewOsBiometrics {
			self.invalidateOnNewOsBiometrics(invalidateOnNewOsBiometrics)
		}

		if let requestHeaders = outOfBandRegistrationMessage.requestHeaders {
			self.requestHeaders(requestHeaders.namesAndValues)
		}

		if outOfBandRegistrationMessage.authenticatorSelectorProvided {
			authenticatorSelector(outOfBandRegistrationOperation.authenticatorSelector)
		}

		if outOfBandRegistrationMessage.pinEnrollerProvided,
		   let pinEnroller = await outOfBandRegistrationOperation.pinEnroller
		{
			self.pinEnroller(pinEnroller)
		}

		let passwordEnroller = outOfBandRegistrationOperation.passwordEnroller
		if outOfBandRegistrationMessage.passwordEnrollerProvided, let passwordEnroller {
			self.passwordEnroller(passwordEnroller)
		}

		if outOfBandRegistrationMessage.biometricUserVerifierProvided {
			biometricUserVerifier(outOfBandRegistrationOperation.biometricUserVerifier)
		}

		if outOfBandRegistrationMessage.devicePasscodeUserVerifierProvided {
			devicePasscodeUserVerifier(outOfBandRegistrationOperation.devicePasscodeUserVerifier)
		}

		if outOfBandRegistrationMessage.onSuccessProvided {
			onSuccess { [unowned outOfBandRegistrationOperation] in
				Task {
					await outOfBandRegistrationOperation.onSuccess(nil)
				}
			}
		}

		if outOfBandRegistrationMessage.onErrorProvided {
			onError { [unowned outOfBandRegistrationOperation] error in
				Task {
					await outOfBandRegistrationOperation.onError(error)
				}
			}
		}

		return self
	}
}
