/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.vfs.provider.sftp;

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import com.jcraft.jsch.Proxy;
import com.jcraft.jsch.ProxyHTTP;
import com.jcraft.jsch.ProxySOCKS5;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemOptions;
import org.apache.commons.vfs.util.Os;

import java.io.File;
import java.util.Properties;

/**
 * Create a JSch Session instance.
 *
 * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
 * @version $Revision$ $Date$
 */
public final class SftpClientFactory
{
    private static final String SSH_DIR_NAME = ".ssh";

    private SftpClientFactory()
    {
    }

    /**
     * Creates a new connection to the server.
     * @param hostname The name of the host to connect to.
     * @param port The port to use.
     * @param username The user's id.
     * @param password The user's password.
     * @param fileSystemOptions The FileSystem options.
     * @return A Session.
     * @throws FileSystemException if an error occurs.
     */
    public static Session createConnection(String hostname, int port, char[] username, char[] password,
                                           FileSystemOptions fileSystemOptions) throws FileSystemException
    {
        JSch jsch = new JSch();

        File sshDir = null;

        // new style - user passed
        File knownHostsFile = SftpFileSystemConfigBuilder.getInstance().getKnownHosts(fileSystemOptions);
        File[] identities = SftpFileSystemConfigBuilder.getInstance().getIdentities(fileSystemOptions);

        if (knownHostsFile != null)
        {
            try
            {
                jsch.setKnownHosts(knownHostsFile.getAbsolutePath());
            }
            catch (JSchException e)
            {
                throw new FileSystemException("vfs.provider.sftp/known-hosts.error",
                    knownHostsFile.getAbsolutePath(), e);
            }
        }
        else
        {
            if (sshDir == null)
            {
                sshDir = findSshDir();
            }
            // Load the known hosts file
            knownHostsFile = new File(sshDir, "known_hosts");
            if (knownHostsFile.isFile() && knownHostsFile.canRead())
            {
                try
                {
                    jsch.setKnownHosts(knownHostsFile.getAbsolutePath());
                }
                catch (JSchException e)
                {
                    throw new FileSystemException("vfs.provider.sftp/known-hosts.error",
                        knownHostsFile.getAbsolutePath(), e);
                }
            }
        }

        if (identities != null)
        {
            for (int iterIdentities = 0; iterIdentities < identities.length; iterIdentities++)
            {
                final File privateKeyFile = identities[iterIdentities];
                try
                {
                    jsch.addIdentity(privateKeyFile.getAbsolutePath());
                }
                catch (final JSchException e)
                {
                    throw new FileSystemException("vfs.provider.sftp/load-private-key.error", privateKeyFile, e);
                }
            }
        }
        else
        {
            if (sshDir == null)
            {
                sshDir = findSshDir();
            }

            // Load the private key (rsa-key only)
            final File privateKeyFile = new File(sshDir, "id_rsa");
            if (privateKeyFile.isFile() && privateKeyFile.canRead())
            {
                try
                {
                    jsch.addIdentity(privateKeyFile.getAbsolutePath());
                }
                catch (final JSchException e)
                {
                    throw new FileSystemException("vfs.provider.sftp/load-private-key.error", privateKeyFile, e);
                }
            }
        }

        Session session;
        try
        {
            session = jsch.getSession(new String(username),
                    hostname,
                    port);
            if (password != null)
            {
                session.setPassword(new String(password));
            }

            Integer timeout = SftpFileSystemConfigBuilder.getInstance().getTimeout(fileSystemOptions);
            if (timeout != null)
            {
                session.setTimeout(timeout.intValue());
            }

            UserInfo userInfo = SftpFileSystemConfigBuilder.getInstance().getUserInfo(fileSystemOptions);
            if (userInfo != null)
            {
                session.setUserInfo(userInfo);
            }

            Properties config = new Properties();

            //set StrictHostKeyChecking property
            String strictHostKeyChecking =
                SftpFileSystemConfigBuilder.getInstance().getStrictHostKeyChecking(fileSystemOptions);
            if (strictHostKeyChecking != null)
            {
                config.setProperty("StrictHostKeyChecking", strictHostKeyChecking);
            }
            //set PreferredAuthentications property
            String preferredAuthentications = SftpFileSystemConfigBuilder.getInstance().
            getPreferredAuthentications(fileSystemOptions);
            if (preferredAuthentications != null)
            {
                config.setProperty("PreferredAuthentications", preferredAuthentications);
            }

            //set compression property
            String compression = SftpFileSystemConfigBuilder.getInstance().getCompression(fileSystemOptions);
            if (compression != null)
            {
                config.setProperty("compression.s2c", compression);
                config.setProperty("compression.c2s", compression);
            }

            String proxyHost = SftpFileSystemConfigBuilder.getInstance().getProxyHost(fileSystemOptions);
            if (proxyHost != null)
            {
                int proxyPort = SftpFileSystemConfigBuilder.getInstance().getProxyPort(fileSystemOptions);
                SftpFileSystemConfigBuilder.ProxyType proxyType =
                    SftpFileSystemConfigBuilder.getInstance().getProxyType(fileSystemOptions);
                Proxy proxy = null;
                if (SftpFileSystemConfigBuilder.PROXY_HTTP.equals(proxyType))
                {
                    if (proxyPort != 0)
                    {
                        proxy = new ProxyHTTP(proxyHost, proxyPort);
                    }
                    else
                    {
                        proxy = new ProxyHTTP(proxyHost);
                    }
                }
                else if (SftpFileSystemConfigBuilder.PROXY_SOCKS5.equals(proxyType))
                {
                    if (proxyPort != 0)
                    {
                        proxy = new ProxySOCKS5(proxyHost, proxyPort);
                    }
                    else
                    {
                        proxy = new ProxySOCKS5(proxyHost);
                    }
                }

                if (proxy != null)
                {
                    session.setProxy(proxy);
                }
            }

            //set properties for the session
            if (config.size() > 0)
            {
                session.setConfig(config);
            }
            session.setDaemonThread(true);
            session.connect();
        }
        catch (final Exception exc)
        {
            throw new FileSystemException("vfs.provider.sftp/connect.error", new Object[]{hostname}, exc);
        }


        return session;
    }

    /**
     * Finds the .ssh directory.
     * <p>The lookup order is:</p>
     * <ol>
     * <li>The system property <code>vfs.sftp.sshdir</code> (the override
     * mechanism)</li>
     * <li><code>{user.home}/.ssh</code></li>
     * <li>On Windows only: C:\cygwin\home\{user.name}\.ssh</li>
     * <li>The current directory, as a last resort.</li>
     * <ol>
     * <p/>
     * Windows Notes:
     * The default installation directory for Cygwin is <code>C:\cygwin</code>.
     * On my set up (Gary here), I have Cygwin in C:\bin\cygwin, not the default.
     * Also, my .ssh directory was created in the {user.home} directory.
     * </p>
     *
     * @return The .ssh directory
     */
    private static File findSshDir()
    {
        String sshDirPath;
        sshDirPath = System.getProperty("vfs.sftp.sshdir");
        if (sshDirPath != null)
        {
            File sshDir = new File(sshDirPath);
            if (sshDir.exists())
            {
                return sshDir;
            }
        }

        File sshDir = new File(System.getProperty("user.home"), SSH_DIR_NAME);
        if (sshDir.exists())
        {
            return sshDir;
        }

        if (Os.isFamily(Os.OS_FAMILY_WINDOWS))
        {
            // TODO - this may not be true
            final String userName = System.getProperty("user.name");
            sshDir = new File("C:\\cygwin\\home\\" + userName + "\\" + SSH_DIR_NAME);
            if (sshDir.exists())
            {
                return sshDir;
            }
        }
        return new File("");
    }
}
