/*
 * Copyright (C) 2019, 2020 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.transport.sshd;

import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.eclipse.jgit.junit.ssh.SshTestHarness;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
import org.eclipse.jgit.util.FS;
import org.junit.After;
import org.junit.Test;

/**
 * Test for using the SshdSessionFactory without files in ~/.ssh but with an
 * in-memory setup.
 */
public class NoFilesSshTest extends SshTestHarness {

	private PublicKey testServerKey;

	private KeyPair testUserKey;

	@Override
	protected SshSessionFactory createSessionFactory() {
		SshdSessionFactory result = new SshdSessionFactory(new JGitKeyCache(),
				null) {

			@Override
			protected File getSshConfig(File dir) {
				return null;
			}

			@Override
			protected ServerKeyDatabase getServerKeyDatabase(File homeDir,
					File dir) {
				return new ServerKeyDatabase() {

					@Override
					public List<PublicKey> lookup(String connectAddress,
							InetSocketAddress remoteAddress,
							Configuration config) {
						return Collections.singletonList(testServerKey);
					}

					@Override
					public boolean accept(String connectAddress,
							InetSocketAddress remoteAddress,
							PublicKey serverKey, Configuration config,
							CredentialsProvider provider) {
						return KeyUtils.compareKeys(serverKey, testServerKey);
					}

				};
			}

			@Override
			protected ConnectorFactory getConnectorFactory() {
				// No ssh-agent in tests
				return null;
			}

			@Override
			protected Iterable<KeyPair> getDefaultKeys(File dir) {
				// This would work for this simple test case:
				// return Collections.singletonList(testUserKey);
				// But let's see if we can check the host and username that's used.
				// For that, we need access to the sshd SessionContext:
				return new KeyAuthenticator();
			}

			@Override
			protected String getDefaultPreferredAuthentications() {
				return "publickey";
			}
		};

		// The home directory is mocked at this point!
		result.setHomeDirectory(FS.DETECTED.userHome());
		result.setSshDirectory(sshDir);
		return result;
	}

	private class KeyAuthenticator implements KeyIdentityProvider, Iterable<KeyPair> {

		@Override
		public Iterator<KeyPair> iterator() {
			// Should not be called. The use of the Iterable interface in
			// SshdSessionFactory.getDefaultKeys() made sense in sshd 2.0.0,
			// but sshd 2.2.0 added the SessionContext, which although good
			// (without it we couldn't check here) breaks the Iterable analogy.
			// But we're stuck now with that interface for getDefaultKeys, and
			// so this override throwing an exception is unfortunately needed.
			throw new UnsupportedOperationException();
		}

		@Override
		public Iterable<KeyPair> loadKeys(SessionContext session)
				throws IOException, GeneralSecurityException {
			if (!TEST_USER.equals(session.getUsername())) {
				return Collections.emptyList();
			}
			SshdSocketAddress remoteAddress = SshdSocketAddress
					.toSshdSocketAddress(session.getRemoteAddress());
			switch (remoteAddress.getHostName()) {
			case "localhost":
			case "127.0.0.1":
				return Collections.singletonList(testUserKey);
			default:
				return Collections.emptyList();
			}
		}
	}

	@After
	public void cleanUp() {
		testServerKey = null;
		testUserKey = null;
	}

	@Override
	protected void installConfig(String... config) {
		File configFile = new File(sshDir, Constants.CONFIG);
		if (config != null) {
			try {
				Files.write(configFile.toPath(), Arrays.asList(config));
			} catch (IOException e) {
				throw new UncheckedIOException(e);
			}
		}
	}

	@Test
	public void testCloneWithBuiltInKeys() throws Exception {
		// This test should fail unless our in-memory setup is taken: no
		// known_hosts file, a config that specifies a non-existing key,
		// and the test is using a newly generated KeyPairs anyway.
		KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
		generator.initialize(2048);
		testUserKey = generator.generateKeyPair();
		KeyPair hostKey = generator.generateKeyPair();
		server.addHostKey(hostKey, true);
		testServerKey = hostKey.getPublic();
		assertNotNull(testServerKey);
		assertNotNull(testUserKey);
		server.setTestUserPublicKey(testUserKey.getPublic());
		cloneWith(
				"ssh://" + TEST_USER + "@localhost:" + testPort
						+ "/doesntmatter",
				new File(getTemporaryDirectory(), "cloned"), null, //
				"Host localhost", //
				"IdentityFile "
						+ new File(sshDir, "does_not_exist").getAbsolutePath());
	}

}
