class LoginExe extends Exelet {

	@Handler(auth = false, instances = VIEWER)
	public static MessageOrBuilder rq_login(ExeletContext context, RQ_Login rq) {
		log.debug("Processing login request from: {}", context.connector.getRemoteAddress());
		var outcome = begin();

		// Validate username
		String username = rq.getUsername();
		if (!ValidationUtil.username(username)) {
			log.debug("The username ({}) is invalid", username);
			return failure(outcome, INVALID_USERNAME);
		}

		User user = UserStore.getByUsername(username).orElse(null);
		if (user == null) {
			log.debug("The user ({}) does not exist", username);
			return failure(outcome, ACCESS_DENIED);
		}

		// Check expiration
		if (user.isExpired()) {
			log.debug("The user ({}) is expired", username);
			return failure(outcome, ACCESS_DENIED);
		}

		// Check OTP if required
		if (user.totpSecret().isPresent()) {
			var key = new SecretKeySpec(user.getTotpSecret(), TOTP.getAlgorithm());
			try {
				if (rq.getTotp() != TOTP.generateOneTimePassword(key, Instant.now())) {
					log.debug("OTP validation failed", username);
					return failure(outcome, ACCESS_DENIED);
				}
			} catch (InvalidKeyException e) {
				log.error("Invalid TOTP secret", e);
				return failure(outcome, ACCESS_DENIED);
			} finally {
				try {
					key.destroy();
				} catch (DestroyFailedException e) {
					log.error("Failed to destroy TOTP secret", e);
					return failure(outcome, ACCESS_DENIED);
				}
			}
		}

		// Check password
		if (!CryptoUtil.PBKDF2.check(rq.getPassword(), user.getHash())) {
			log.debug("Password validation failed", username);
			return failure(outcome, ACCESS_DENIED);
		}

		log.debug("Accepting login request for user: {}", username);

		// Mark connection as authenticated
		context.connector.authenticate();

		// Update login metadata
		ProfileStore.getViewer(username).ifPresentOrElse(profile -> {
			profile.viewer().ip().set(context.connector.getRemoteAddress());
		}, () -> {
			ProfileStore.create(profile -> {
				profile.uuid().set(context.connector.getRemoteUuid());
				profile.instanceType().set(context.connector.getRemoteInstance());
				profile.instanceFlavor().set(context.connector.getRemoteInstanceFlavor());
				profile.viewer().username().set(username);
				profile.viewer().ip().set(context.connector.getRemoteAddress());
			});
		});

		return success(outcome);
	}

	private  LoginExe();

}