/*
 * Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com>
 * Copyright (C) 2008-2009, Google Inc.
 * Copyright (C) 2009, Google, Inc.
 * Copyright (C) 2009, JetBrains s.r.o.
 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> 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;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.util.io.IsolatedOutputStream;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

/**
 * Run remote commands using Jsch.
 * <p>
 * This class is the default session implementation using Jsch. Note that
 * {@link org.eclipse.jgit.transport.JschConfigSessionFactory} is used to create
 * the actual session passed to the constructor.
 */
public class JschSession implements RemoteSession {
	final Session sock;
	final URIish uri;

	/**
	 * Create a new session object by passing the real Jsch session and the URI
	 * information.
	 *
	 * @param session
	 *            the real Jsch session created elsewhere.
	 * @param uri
	 *            the URI information for the remote connection
	 */
	public JschSession(Session session, URIish uri) {
		sock = session;
		this.uri = uri;
	}

	/** {@inheritDoc} */
	@Override
	public Process exec(String command, int timeout) throws IOException {
		return new JschProcess(command, timeout);
	}

	/** {@inheritDoc} */
	@Override
	public void disconnect() {
		if (sock.isConnected())
			sock.disconnect();
	}

	/**
	 * A kludge to allow {@link org.eclipse.jgit.transport.TransportSftp} to get
	 * an Sftp channel from Jsch. Ideally, this method would be generic, which
	 * would require implementing generic Sftp channel operations in the
	 * RemoteSession class.
	 *
	 * @return a channel suitable for Sftp operations.
	 * @throws com.jcraft.jsch.JSchException
	 *             on problems getting the channel.
	 * @deprecated since 5.2; use {@link #getFtpChannel()} instead
	 */
	@Deprecated
	public Channel getSftpChannel() throws JSchException {
		return sock.openChannel("sftp"); //$NON-NLS-1$
	}

	/**
	 * {@inheritDoc}
	 *
	 * @since 5.2
	 */
	@Override
	public FtpChannel getFtpChannel() {
		return new JschFtpChannel();
	}

	/**
	 * Implementation of Process for running a single command using Jsch.
	 * <p>
	 * Uses the Jsch session to do actual command execution and manage the
	 * execution.
	 */
	private class JschProcess extends Process {
		private ChannelExec channel;

		final int timeout;

		private InputStream inputStream;

		private OutputStream outputStream;

		private InputStream errStream;

		/**
		 * Opens a channel on the session ("sock") for executing the given
		 * command, opens streams, and starts command execution.
		 *
		 * @param commandName
		 *            the command to execute
		 * @param tms
		 *            the timeout value, in seconds, for the command.
		 * @throws TransportException
		 *             on problems opening a channel or connecting to the remote
		 *             host
		 * @throws IOException
		 *             on problems opening streams
		 */
		JschProcess(String commandName, int tms)
				throws TransportException, IOException {
			timeout = tms;
			try {
				channel = (ChannelExec) sock.openChannel("exec"); //$NON-NLS-1$
				channel.setCommand(commandName);
				setupStreams();
				channel.connect(timeout > 0 ? timeout * 1000 : 0);
				if (!channel.isConnected()) {
					closeOutputStream();
					throw new TransportException(uri,
							JGitText.get().connectionFailed);
				}
			} catch (JSchException e) {
				closeOutputStream();
				throw new TransportException(uri, e.getMessage(), e);
			}
		}

		private void closeOutputStream() {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException ioe) {
					// ignore
				}
			}
		}

		private void setupStreams() throws IOException {
			inputStream = channel.getInputStream();

			// JSch won't let us interrupt writes when we use our InterruptTimer
			// to break out of a long-running write operation. To work around
			// that we spawn a background thread to shuttle data through a pipe,
			// as we can issue an interrupted write out of that. Its slower, so
			// we only use this route if there is a timeout.
			OutputStream out = channel.getOutputStream();
			if (timeout <= 0) {
				outputStream = out;
			} else {
				IsolatedOutputStream i = new IsolatedOutputStream(out);
				outputStream = new BufferedOutputStream(i, 16 * 1024);
			}

			errStream = channel.getErrStream();
		}

		@Override
		public InputStream getInputStream() {
			return inputStream;
		}

		@Override
		public OutputStream getOutputStream() {
			return outputStream;
		}

		@Override
		public InputStream getErrorStream() {
			return errStream;
		}

		@Override
		public int exitValue() {
			if (isRunning())
				throw new IllegalStateException();
			return channel.getExitStatus();
		}

		private boolean isRunning() {
			return channel.getExitStatus() < 0 && channel.isConnected();
		}

		@Override
		public void destroy() {
			if (channel.isConnected())
				channel.disconnect();
			closeOutputStream();
		}

		@Override
		public int waitFor() throws InterruptedException {
			while (isRunning())
				Thread.sleep(100);
			return exitValue();
		}
	}

	private class JschFtpChannel implements FtpChannel {

		private ChannelSftp ftp;

		@Override
		public void connect(int timeout, TimeUnit unit) throws IOException {
			try {
				ftp = (ChannelSftp) sock.openChannel("sftp"); //$NON-NLS-1$
				ftp.connect((int) unit.toMillis(timeout));
			} catch (JSchException e) {
				ftp = null;
				throw new IOException(e.getLocalizedMessage(), e);
			}
		}

		@Override
		public void disconnect() {
			ftp.disconnect();
			ftp = null;
		}

		private <T> T map(Callable<T> op) throws IOException {
			try {
				return op.call();
			} catch (Exception e) {
				if (e instanceof SftpException) {
					throw new FtpChannel.FtpException(e.getLocalizedMessage(),
							((SftpException) e).id, e);
				}
				throw new IOException(e.getLocalizedMessage(), e);
			}
		}

		@Override
		public boolean isConnected() {
			return ftp != null && sock.isConnected();
		}

		@Override
		public void cd(String path) throws IOException {
			map(() -> {
				ftp.cd(path);
				return null;
			});
		}

		@Override
		public String pwd() throws IOException {
			return map(() -> ftp.pwd());
		}

		@Override
		public Collection<DirEntry> ls(String path) throws IOException {
			return map(() -> {
				List<DirEntry> result = new ArrayList<>();
				for (Object e : ftp.ls(path)) {
					ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) e;
					result.add(new DirEntry() {

						@Override
						public String getFilename() {
							return entry.getFilename();
						}

						@Override
						public long getModifiedTime() {
							return entry.getAttrs().getMTime();
						}

						@Override
						public boolean isDirectory() {
							return entry.getAttrs().isDir();
						}
					});
				}
				return result;
			});
		}

		@Override
		public void rmdir(String path) throws IOException {
			map(() -> {
				ftp.rm(path);
				return null;
			});
		}

		@Override
		public void mkdir(String path) throws IOException {
			map(() -> {
				ftp.mkdir(path);
				return null;
			});
		}

		@Override
		public InputStream get(String path) throws IOException {
			return map(() -> ftp.get(path));
		}

		@Override
		public OutputStream put(String path) throws IOException {
			return map(() -> ftp.put(path));
		}

		@Override
		public void rm(String path) throws IOException {
			map(() -> {
				ftp.rm(path);
				return null;
			});
		}

		@Override
		public void rename(String from, String to) throws IOException {
			map(() -> {
				// Plain FTP rename will fail if "to" exists. Jsch knows about
				// the FTP extension "posix-rename@openssh.com", which will
				// remove "to" first if it exists.
				if (hasPosixRename()) {
					ftp.rename(from, to);
				} else if (!to.equals(from)) {
					// Try to remove "to" first. With git, we typically get this
					// when a lock file is moved over the file locked. Note that
					// the check for to being equal to from may still fail in
					// the general case, but for use with JGit's TransportSftp
					// it should be good enough.
					delete(to);
					ftp.rename(from, to);
				}
				return null;
			});
		}

		/**
		 * Determine whether the server has the posix-rename extension.
		 *
		 * @return {@code true} if it is supported, {@code false} otherwise
		 * @see <a href=
		 *      "https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD">OpenSSH
		 *      deviations and extensions to the published SSH protocol</a>
		 * @see <a href=
		 *      "http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html">stdio.h:
		 *      rename()</a>
		 */
		private boolean hasPosixRename() {
			return "1".equals(ftp.getExtension("posix-rename@openssh.com")); //$NON-NLS-1$//$NON-NLS-2$
		}
	}
}
