/*
 * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.transport.sshd;

import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyPair;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import org.apache.sshd.client.ClientBuilder;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.auth.UserAuth;
import org.apache.sshd.client.auth.keyboard.UserAuthKeyboardInteractiveFactory;
import org.apache.sshd.client.auth.pubkey.UserAuthPublicKeyFactory;
import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.compression.BuiltinCompressions;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.loader.openssh.kdf.BCryptKdfOptions;
import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.transport.sshd.CachingKeyPairProvider;
import org.eclipse.jgit.internal.transport.sshd.GssApiWithMicAuthFactory;
import org.eclipse.jgit.internal.transport.sshd.JGitPasswordAuthFactory;
import org.eclipse.jgit.internal.transport.sshd.JGitSshClient;
import org.eclipse.jgit.internal.transport.sshd.JGitSshConfig;
import org.eclipse.jgit.internal.transport.sshd.JGitUserInteraction;
import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyVerifier;
import org.eclipse.jgit.internal.transport.sshd.PasswordProviderWrapper;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshConstants;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;

/**
 * A {@link SshSessionFactory} that uses Apache MINA sshd. Classes from Apache
 * MINA sshd are kept private to avoid API evolution problems when Apache MINA
 * sshd interfaces change.
 *
 * @since 5.2
 */
public class SshdSessionFactory extends SshSessionFactory implements Closeable {

	private final AtomicBoolean closing = new AtomicBoolean();

	private final Set<SshdSession> sessions = new HashSet<>();

	private final Map<Tuple, HostConfigEntryResolver> defaultHostConfigEntryResolver = new ConcurrentHashMap<>();

	private final Map<Tuple, ServerKeyVerifier> defaultServerKeyVerifier = new ConcurrentHashMap<>();

	private final Map<Tuple, Iterable<KeyPair>> defaultKeys = new ConcurrentHashMap<>();

	private final KeyCache keyCache;

	private final ProxyDataFactory proxies;

	private File sshDirectory;

	private File homeDirectory;

	/**
	 * Creates a new {@link SshdSessionFactory} without key cache and a
	 * {@link DefaultProxyDataFactory}.
	 */
	public SshdSessionFactory() {
		this(null, new DefaultProxyDataFactory());
	}

	/**
	 * Creates a new {@link SshdSessionFactory} using the given {@link KeyCache}
	 * and {@link ProxyDataFactory}. The {@code keyCache} is used for all sessions
	 * created through this session factory; cached keys are destroyed when the
	 * session factory is {@link #close() closed}.
	 * <p>
	 * Caching ssh keys in memory for an extended period of time is generally
	 * considered bad practice, but there may be circumstances where using a
	 * {@link KeyCache} is still the right choice, for instance to avoid that a
	 * user gets prompted several times for the same password for the same key.
	 * In general, however, it is preferable <em>not</em> to use a key cache but
	 * to use a {@link #createKeyPasswordProvider(CredentialsProvider)
	 * KeyPasswordProvider} that has access to some secure storage and can save
	 * and retrieve passwords from there without user interaction. Another
	 * approach is to use an ssh agent.
	 * </p>
	 * <p>
	 * Note that the underlying ssh library (Apache MINA sshd) may or may not
	 * keep ssh keys in memory for unspecified periods of time irrespective of
	 * the use of a {@link KeyCache}.
	 * </p>
	 *
	 * @param keyCache
	 *            {@link KeyCache} to use for caching ssh keys, or {@code null}
	 *            to not use a key cache
	 * @param proxies
	 *            {@link ProxyDataFactory} to use, or {@code null} to not use a
	 *            proxy database (in which case connections through proxies will
	 *            not be possible)
	 */
	public SshdSessionFactory(KeyCache keyCache, ProxyDataFactory proxies) {
		super();
		this.keyCache = keyCache;
		this.proxies = proxies;
		// sshd limits the number of BCrypt KDF rounds to 255 by default.
		// Decrypting such a key takes about two seconds on my machine.
		// I consider this limit too low. The time increases linearly with the
		// number of rounds.
		BCryptKdfOptions.setMaxAllowedRounds(16384);
	}

	/** A simple general map key. */
	private static final class Tuple {
		private Object[] objects;

		public Tuple(Object[] objects) {
			this.objects = objects;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == this) {
				return true;
			}
			if (obj != null && obj.getClass() == Tuple.class) {
				Tuple other = (Tuple) obj;
				return Arrays.equals(objects, other.objects);
			}
			return false;
		}

		@Override
		public int hashCode() {
			return Arrays.hashCode(objects);
		}
	}

	// We can't really use a single client. Clients need to be stopped
	// properly, and we don't really know when to do that. Instead we use
	// a dedicated SshClient instance per session. We need a bit of caching to
	// avoid re-loading the ssh config and keys repeatedly.

	@Override
	public SshdSession getSession(URIish uri,
			CredentialsProvider credentialsProvider, FS fs, int tms)
			throws TransportException {
		SshdSession session = null;
		try {
			session = new SshdSession(uri, () -> {
				File home = getHomeDirectory();
				if (home == null) {
					// Always use the detected filesystem for the user home!
					// It makes no sense to have different "user home"
					// directories depending on what file system a repository
					// is.
					home = FS.DETECTED.userHome();
				}
				File sshDir = getSshDirectory();
				if (sshDir == null) {
					sshDir = new File(home, SshConstants.SSH_DIR);
				}
				HostConfigEntryResolver configFile = getHostConfigEntryResolver(
						home, sshDir);
				KeyIdentityProvider defaultKeysProvider = toKeyIdentityProvider(
						getDefaultKeys(sshDir));
				KeyPasswordProvider passphrases = createKeyPasswordProvider(
						credentialsProvider);
				SshClient client = ClientBuilder.builder()
						.factory(JGitSshClient::new)
						.filePasswordProvider(
								createFilePasswordProvider(passphrases))
						.hostConfigEntryResolver(configFile)
						.serverKeyVerifier(getServerKeyVerifier(home, sshDir))
						.compressionFactories(
								new ArrayList<>(BuiltinCompressions.VALUES))
						.build();
				client.setUserInteraction(
						new JGitUserInteraction(credentialsProvider));
				client.setUserAuthFactories(getUserAuthFactories());
				client.setKeyIdentityProvider(defaultKeysProvider);
				// JGit-specific things:
				JGitSshClient jgitClient = (JGitSshClient) client;
				jgitClient.setKeyCache(getKeyCache());
				jgitClient.setCredentialsProvider(credentialsProvider);
				jgitClient.setProxyDatabase(proxies);
				String defaultAuths = getDefaultPreferredAuthentications();
				if (defaultAuths != null) {
					jgitClient.setAttribute(
							JGitSshClient.PREFERRED_AUTHENTICATIONS,
							defaultAuths);
				}
				// Other things?
				return client;
			});
			session.addCloseListener(s -> unregister(s));
			register(session);
			session.connect(Duration.ofMillis(tms));
			return session;
		} catch (Exception e) {
			unregister(session);
			throw new TransportException(uri, e.getMessage(), e);
		}
	}

	@Override
	public void close() {
		closing.set(true);
		boolean cleanKeys = false;
		synchronized (this) {
			cleanKeys = sessions.isEmpty();
		}
		if (cleanKeys) {
			KeyCache cache = getKeyCache();
			if (cache != null) {
				cache.close();
			}
		}
	}

	private void register(SshdSession newSession) throws IOException {
		if (newSession == null) {
			return;
		}
		if (closing.get()) {
			throw new IOException(SshdText.get().sshClosingDown);
		}
		synchronized (this) {
			sessions.add(newSession);
		}
	}

	private void unregister(SshdSession oldSession) {
		boolean cleanKeys = false;
		synchronized (this) {
			sessions.remove(oldSession);
			cleanKeys = closing.get() && sessions.isEmpty();
		}
		if (cleanKeys) {
			KeyCache cache = getKeyCache();
			if (cache != null) {
				cache.close();
			}
		}
	}

	/**
	 * Set a global directory to use as the user's home directory
	 *
	 * @param homeDir
	 *            to use
	 */
	public void setHomeDirectory(@NonNull File homeDir) {
		if (homeDir.isAbsolute()) {
			homeDirectory = homeDir;
		} else {
			homeDirectory = homeDir.getAbsoluteFile();
		}
	}

	/**
	 * Retrieves the global user home directory
	 *
	 * @return the directory, or {@code null} if not set
	 */
	public File getHomeDirectory() {
		return homeDirectory;
	}

	/**
	 * Set a global directory to use as the .ssh directory
	 *
	 * @param sshDir
	 *            to use
	 */
	public void setSshDirectory(@NonNull File sshDir) {
		if (sshDir.isAbsolute()) {
			sshDirectory = sshDir;
		} else {
			sshDirectory = sshDir.getAbsoluteFile();
		}
	}

	/**
	 * Retrieves the global .ssh directory
	 *
	 * @return the directory, or {@code null} if not set
	 */
	public File getSshDirectory() {
		return sshDirectory;
	}

	/**
	 * Obtain a {@link HostConfigEntryResolver} to read the ssh config file and
	 * to determine host entries for connections.
	 *
	 * @param homeDir
	 *            home directory to use for ~ replacement
	 * @param sshDir
	 *            to use for looking for the config file
	 * @return the resolver
	 */
	@NonNull
	private HostConfigEntryResolver getHostConfigEntryResolver(
			@NonNull File homeDir, @NonNull File sshDir) {
		return defaultHostConfigEntryResolver.computeIfAbsent(
				new Tuple(new Object[] { homeDir, sshDir }),
				t -> new JGitSshConfig(homeDir,
						new File(sshDir, SshConstants.CONFIG),
						getLocalUserName()));
	}

	/**
	 * Obtain a {@link ServerKeyVerifier} to read known_hosts files and to
	 * verify server host keys. The default implementation returns a
	 * {@link ServerKeyVerifier} that recognizes the two openssh standard files
	 * {@code ~/.ssh/known_hosts} and {@code ~/.ssh/known_hosts2} as well as any
	 * files configured via the {@code UserKnownHostsFile} option in the ssh
	 * config file.
	 *
	 * @param homeDir
	 *            home directory to use for ~ replacement
	 * @param sshDir
	 *            representing ~/.ssh/
	 * @return the resolver
	 */
	@NonNull
	private ServerKeyVerifier getServerKeyVerifier(@NonNull File homeDir,
			@NonNull File sshDir) {
		return defaultServerKeyVerifier.computeIfAbsent(
				new Tuple(new Object[] { homeDir, sshDir }),
				t -> new OpenSshServerKeyVerifier(true,
						getDefaultKnownHostsFiles(sshDir)));
	}

	/**
	 * Gets the list of default user known hosts files. The default returns
	 * ~/.ssh/known_hosts and ~/.ssh/known_hosts2. The ssh config
	 * {@code UserKnownHostsFile} overrides this default.
	 *
	 * @param sshDir
	 * @return the possibly empty list of default known host file paths.
	 */
	@NonNull
	protected List<Path> getDefaultKnownHostsFiles(@NonNull File sshDir) {
		return Arrays.asList(sshDir.toPath().resolve(SshConstants.KNOWN_HOSTS),
				sshDir.toPath().resolve(SshConstants.KNOWN_HOSTS + '2'));
	}

	/**
	 * Determines the default keys. The default implementation will lazy load
	 * the {@link #getDefaultIdentities(File) default identity files}.
	 * <p>
	 * Subclasses may override and return an {@link Iterable} of whatever keys
	 * are appropriate. If the returned iterable lazily loads keys, it should be
	 * an instance of
	 * {@link org.apache.sshd.common.keyprovider.AbstractResourceKeyPairProvider
	 * AbstractResourceKeyPairProvider} so that the session can later pass it
	 * the {@link #createKeyPasswordProvider(CredentialsProvider) password
	 * provider} wrapped as a {@link FilePasswordProvider} via
	 * {@link org.apache.sshd.common.keyprovider.AbstractResourceKeyPairProvider#setPasswordFinder(FilePasswordProvider)
	 * AbstractResourceKeyPairProvider#setPasswordFinder(FilePasswordProvider)}
	 * so that encrypted, password-protected keys can be loaded.
	 * </p>
	 * <p>
	 * The default implementation uses exactly this mechanism; class
	 * {@link CachingKeyPairProvider} may serve as a model for a customized
	 * lazy-loading {@link Iterable} implementation
	 * </p>
	 * <p>
	 * If the {@link Iterable} returned has the keys already pre-loaded or
	 * otherwise doesn't need to decrypt encrypted keys, it can be any
	 * {@link Iterable}, for instance a simple {@link java.util.List List}.
	 * </p>
	 *
	 * @param sshDir
	 *            to look in for keys
	 * @return an {@link Iterable} over the default keys
	 * @since 5.3
	 */
	@NonNull
	protected Iterable<KeyPair> getDefaultKeys(@NonNull File sshDir) {
		List<Path> defaultIdentities = getDefaultIdentities(sshDir);
		return defaultKeys.computeIfAbsent(
				new Tuple(defaultIdentities.toArray(new Path[0])),
				t -> new CachingKeyPairProvider(defaultIdentities,
						getKeyCache()));
	}

	/**
	 * Converts an {@link Iterable} of {link KeyPair}s into a
	 * {@link KeyIdentityProvider}.
	 *
	 * @param keys
	 *            to provide via the returned {@link KeyIdentityProvider}
	 * @return a {@link KeyIdentityProvider} that provides the given
	 *         {@code keys}
	 */
	private KeyIdentityProvider toKeyIdentityProvider(Iterable<KeyPair> keys) {
		if (keys instanceof KeyIdentityProvider) {
			return (KeyIdentityProvider) keys;
		}
		return (session) -> keys;
	}

	/**
	 * Gets a list of default identities, i.e., private key files that shall
	 * always be tried for public key authentication. Typically those are
	 * ~/.ssh/id_dsa, ~/.ssh/id_rsa, and so on. The default implementation
	 * returns the files defined in {@link SshConstants#DEFAULT_IDENTITIES}.
	 *
	 * @param sshDir
	 *            the directory that represents ~/.ssh/
	 * @return a possibly empty list of paths containing default identities
	 *         (private keys)
	 */
	@NonNull
	protected List<Path> getDefaultIdentities(@NonNull File sshDir) {
		return Arrays
				.asList(SshConstants.DEFAULT_IDENTITIES).stream()
				.map(s -> new File(sshDir, s).toPath()).filter(Files::exists)
				.collect(Collectors.toList());
	}

	/**
	 * Obtains the {@link KeyCache} to use to cache loaded keys.
	 *
	 * @return the {@link KeyCache}, or {@code null} if none.
	 */
	protected final KeyCache getKeyCache() {
		return keyCache;
	}

	/**
	 * Creates a {@link KeyPasswordProvider} for a new session.
	 *
	 * @param provider
	 *            the {@link CredentialsProvider} to delegate to for user
	 *            interactions
	 * @return a new {@link KeyPasswordProvider}
	 */
	@NonNull
	protected KeyPasswordProvider createKeyPasswordProvider(
			CredentialsProvider provider) {
		return new IdentityPasswordProvider(provider);
	}

	/**
	 * Creates a {@link FilePasswordProvider} for a new session.
	 *
	 * @param provider
	 *            the {@link KeyPasswordProvider} to delegate to
	 * @return a new {@link FilePasswordProvider}
	 */
	@NonNull
	private FilePasswordProvider createFilePasswordProvider(
			KeyPasswordProvider provider) {
		return new PasswordProviderWrapper(provider);
	}

	/**
	 * Gets the user authentication mechanisms (or rather, factories for them).
	 * By default this returns gssapi-with-mic, public-key, password, and
	 * keyboard-interactive, in that order. The order is only significant if the
	 * ssh config does <em>not</em> set {@code PreferredAuthentications}; if it
	 * is set, the order defined there will be taken.
	 *
	 * @return the non-empty list of factories.
	 */
	@NonNull
	private List<NamedFactory<UserAuth>> getUserAuthFactories() {
		// About the order of password and keyboard-interactive, see upstream
		// bug https://issues.apache.org/jira/projects/SSHD/issues/SSHD-866 .
		// Password auth doesn't have this problem.
		return Collections.unmodifiableList(
				Arrays.asList(GssApiWithMicAuthFactory.INSTANCE,
						UserAuthPublicKeyFactory.INSTANCE,
						JGitPasswordAuthFactory.INSTANCE,
						UserAuthKeyboardInteractiveFactory.INSTANCE));
	}

	/**
	 * Gets the list of default preferred authentication mechanisms. If
	 * {@code null} is returned the openssh default list will be in effect. If
	 * the ssh config defines {@code PreferredAuthentications} the value from
	 * the ssh config takes precedence.
	 *
	 * @return a comma-separated list of algorithm names, or {@code null} if
	 *         none
	 */
	protected String getDefaultPreferredAuthentications() {
		return null;
	}
}
