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

import NevisMobileAuthentication

final class PasswordPolicyImpl: PasswordPolicy, Codable, Sendable {
	// MARK: Properties

	let operationId: String

	// MARK: Initialization

	init(operationId: String) {
		self.operationId = operationId
	}

	// MARK: PasswordPolicy

	func validatePasswordForEnrollment(_ password: String,
	                                   onSuccess: @escaping @Sendable () -> (),
	                                   onError: @escaping @Sendable (PasswordEnrollmentValidationError) -> ())
	{
		Task {
			let operation: any UserInteractionOperation = await OperationCache.shared.read(by: operationId)
			let authenticator = await operation.findAuthenticator(aaid: AuthenticatorAaid.Password)
			let state = PasswordValidateForEnrollmentState(authenticator: authenticator,
			                                               onSuccess: onSuccess,
			                                               onValidationError: onError)
			await OperationCache.shared.update(by: operationId,
			                                   operation: operation.update(state: state))

			let message = PasswordValidationMessage(operationId: operationId,
			                                        password: password)
			EventEmitter.shared.dispatch(event: .passwordValidateForEnrollment, message: message)
		}
	}

	func validatePasswordForPasswordChange(_ password: String,
	                                       onSuccess: @escaping @Sendable () -> (),
	                                       onError: @escaping @Sendable (PasswordChangeValidationError) -> ())
	{
		Task {
			let operation: PasswordChangeOperation = await OperationCache.shared.read(by: operationId)
			let state = PasswordValidateForPasswordChangeState(onSuccess: onSuccess,
			                                                   onValidationError: onError)
			await OperationCache.shared.update(by: operationId,
			                                   operation: operation.update(state: state))

			let message = PasswordValidationMessage(operationId: operationId,
			                                        password: password)
			EventEmitter.shared.dispatch(event: .passwordValidateForPasswordChange, message: message)
		}
	}
}
