/*
 * Copyright (C) 2022 Thomas Wolf <thomas.wolf@paranor.ch> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.internal.transport.sshd;

import static org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider.getKeyId;

import java.security.KeyPair;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.sshd.client.auth.password.PasswordAuthenticationReporter;
import org.apache.sshd.client.auth.password.UserAuthPassword;
import org.apache.sshd.client.auth.pubkey.PublicKeyAuthenticationReporter;
import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.config.keys.KeyUtils;

/**
 * Provides a log of authentication attempts for a {@link ClientSession}.
 */
public class AuthenticationLogger {

	private final List<String> messages = new ArrayList<>();

	// We're interested in this log only in the failure case, so we don't need
	// to log authentication success.

	private final PublicKeyAuthenticationReporter pubkeyLogger = new PublicKeyAuthenticationReporter() {

		private boolean hasAttempts;

		@Override
		public void signalAuthenticationAttempt(ClientSession session,
				String service, KeyPair identity, String signature)
				throws Exception {
			hasAttempts = true;
			String message;
			if (identity.getPrivate() == null) {
				// SSH agent key
				message = MessageFormat.format(
						SshdText.get().authPubkeyAttemptAgent,
						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
						getKeyId(session, identity), signature);
			} else {
				message = MessageFormat.format(
						SshdText.get().authPubkeyAttempt,
						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
						getKeyId(session, identity), signature);
			}
			messages.add(message);
		}

		@Override
		public void signalAuthenticationExhausted(ClientSession session,
				String service) throws Exception {
			String message;
			if (hasAttempts) {
				message = MessageFormat.format(
						SshdText.get().authPubkeyExhausted,
						UserAuthPublicKey.NAME);
			} else {
				message = MessageFormat.format(SshdText.get().authPubkeyNoKeys,
						UserAuthPublicKey.NAME);
			}
			messages.add(message);
			hasAttempts = false;
		}

		@Override
		public void signalAuthenticationFailure(ClientSession session,
				String service, KeyPair identity, boolean partial,
				List<String> serverMethods) throws Exception {
			String message;
			if (partial) {
				message = MessageFormat.format(
						SshdText.get().authPubkeyPartialSuccess,
						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
						getKeyId(session, identity), serverMethods);
			} else {
				message = MessageFormat.format(
						SshdText.get().authPubkeyFailure,
						UserAuthPublicKey.NAME, KeyUtils.getKeyType(identity),
						getKeyId(session, identity));
			}
			messages.add(message);
		}
	};

	private final PasswordAuthenticationReporter passwordLogger = new PasswordAuthenticationReporter() {

		private int attempts;

		@Override
		public void signalAuthenticationAttempt(ClientSession session,
				String service, String oldPassword, boolean modified,
				String newPassword) throws Exception {
			attempts++;
			String message;
			if (modified) {
				message = MessageFormat.format(
						SshdText.get().authPasswordChangeAttempt,
						UserAuthPassword.NAME, Integer.valueOf(attempts));
			} else {
				message = MessageFormat.format(
						SshdText.get().authPasswordAttempt,
						UserAuthPassword.NAME, Integer.valueOf(attempts));
			}
			messages.add(message);
		}

		@Override
		public void signalAuthenticationExhausted(ClientSession session,
				String service) throws Exception {
			String message;
			if (attempts > 0) {
				message = MessageFormat.format(
						SshdText.get().authPasswordExhausted,
						UserAuthPassword.NAME);
			} else {
				message = MessageFormat.format(
						SshdText.get().authPasswordNotTried,
						UserAuthPassword.NAME);
			}
			messages.add(message);
			attempts = 0;
		}

		@Override
		public void signalAuthenticationFailure(ClientSession session,
				String service, String password, boolean partial,
				List<String> serverMethods) throws Exception {
			String message;
			if (partial) {
				message = MessageFormat.format(
						SshdText.get().authPasswordPartialSuccess,
						UserAuthPassword.NAME, serverMethods);
			} else {
				message = MessageFormat.format(
						SshdText.get().authPasswordFailure,
						UserAuthPassword.NAME);
			}
			messages.add(message);
		}
	};

	private final GssApiWithMicAuthenticationReporter gssLogger = new GssApiWithMicAuthenticationReporter() {

		private boolean hasAttempts;

		@Override
		public void signalAuthenticationAttempt(ClientSession session,
				String service, String mechanism) {
			hasAttempts = true;
			String message = MessageFormat.format(
					SshdText.get().authGssApiAttempt,
					GssApiWithMicAuthFactory.NAME, mechanism);
			messages.add(message);
		}

		@Override
		public void signalAuthenticationExhausted(ClientSession session,
				String service) {
			String message;
			if (hasAttempts) {
				message = MessageFormat.format(
						SshdText.get().authGssApiExhausted,
						GssApiWithMicAuthFactory.NAME);
			} else {
				message = MessageFormat.format(
						SshdText.get().authGssApiNotTried,
						GssApiWithMicAuthFactory.NAME);
			}
			messages.add(message);
			hasAttempts = false;
		}

		@Override
		public void signalAuthenticationFailure(ClientSession session,
				String service, String mechanism, boolean partial,
				List<String> serverMethods) {
			String message;
			if (partial) {
				message = MessageFormat.format(
						SshdText.get().authGssApiPartialSuccess,
						GssApiWithMicAuthFactory.NAME, mechanism,
						serverMethods);
			} else {
				message = MessageFormat.format(
						SshdText.get().authGssApiFailure,
						GssApiWithMicAuthFactory.NAME, mechanism);
			}
			messages.add(message);
		}
	};

	/**
	 * Creates a new {@link AuthenticationLogger} and configures the
	 * {@link ClientSession} to report authentication attempts through this
	 * instance.
	 *
	 * @param session
	 *            to configure
	 */
	public AuthenticationLogger(ClientSession session) {
		session.setPublicKeyAuthenticationReporter(pubkeyLogger);
		session.setPasswordAuthenticationReporter(passwordLogger);
		session.setAttribute(
				GssApiWithMicAuthenticationReporter.GSS_AUTHENTICATION_REPORTER,
				gssLogger);
		// TODO: keyboard-interactive? sshd 2.8.0 has no callback
		// interface for it.
	}

	/**
	 * Retrieves the log messages for the authentication attempts.
	 *
	 * @return the messages as an unmodifiable list
	 */
	public List<String> getLog() {
		return Collections.unmodifiableList(messages);
	}

	/**
	 * Drops all previously recorded log messages.
	 */
	public void clear() {
		messages.clear();
	}
}
