// Path: src/main/java/com/sonymobile/tools/gerrit/gerritevents/GerritDefaultValues.java
// public final class GerritDefaultValues {
// 
//     /**
//      * Default private constructor to hinder instantiation.
//      */
//     private GerritDefaultValues() {
// 
//     }
//     /**
//      * The default gerrit name.
//      */
//     public static final String DEFAULT_GERRIT_NAME = "";
//     /**
//      * The default gerrit hostname.
//      */
//     public static final String DEFAULT_GERRIT_HOSTNAME = "";
//     /**
//      * The default gerrit front end url.
//      */
//     public static final String DEFAULT_GERRIT_FRONT_END_URL = "";
//     /**
//      * The default ssh port for the gerrit server.
//      */
//     public static final int DEFAULT_GERRIT_SSH_PORT = 29418;
//     /**
//      * The default scheme for the gerrit server.
//      */
//     public static final String DEFAULT_GERRIT_SCHEME = "ssh";
//     /**
//      * The default gerrit proxy.
//      */
//     public static final String DEFAULT_GERRIT_PROXY = "";
//     /**
//      * The default gerrit ssh connection timeout.
//      */
//     public static final int DEFAULT_GERRIT_SSH_CONNECTION_TIMEOUT = 0;
// 
//     /**
//      * The default key-file to use when authenticating to the gerrit server.
//      */
//     public static final File DEFAULT_GERRIT_AUTH_KEY_FILE = new File(new File(System.getProperty("user.home"), ".ssh"),
//                                                               "id_rsa");
//     /**
//      * The default password for the private key-file.
//      */
//     public static final String DEFAULT_GERRIT_AUTH_KEY_FILE_PASSWORD = null;
//     /**
//      * The default username to use when authenticating to the gerrit server.
//      */
//     public static final String DEFAULT_GERRIT_USERNAME = "";
//     /**
//      * The default nr of event worker threads.
//      */
//     public static final int DEFAULT_NR_OF_RECEIVING_WORKER_THREADS = 3;
//     /**
//      * The default keep alive time for receiving threads in seconds.
//      */
//     public static final int DEFAULT_RECEIVE_THREAD_KEEP_ALIVE_TIME = 1200;
//     /**
//      * The minimum keep alive time for receiving threads in seconds.
//      */
//     public static final int MIN_RECEIVE_THREAD_KEEP_ALIVE_TIME = 10;
//     /**
//      * The default nr of worker threads that sends approvals/review commands.
//      */
//     public static final int DEFAULT_NR_OF_SENDING_WORKER_THREADS = 1;
//     /**
//      * The default build schedule delay.
//      */
//     public static final int DEFAULT_BUILD_SCHEDULE_DELAY = 3;
//     /**
//      * The default refresh interval for the Dynamic Trigger Configuration.
//      */
//     public static final int DEFAULT_DYNAMIC_CONFIG_REFRESH_INTERVAL = 30;
// 
//     /**
//      * The minimum refresh interval for dynamic configuration.
//      */
//     public static final int MINIMUM_DYNAMIC_CONFIG_REFRESH_INTERVAL = 5;
// }


import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.HostKeyRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.ProxyHTTP;
import com.jcraft.jsch.ProxySOCKS5;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues;
/*
 * The MIT License
 *
 * Copyright 2011 Sony Ericsson Mobile Communications. All rights reserved.
 * Copyright 2014 Sony Mobile Communications AB. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.sonymobile.tools.gerrit.gerritevents.ssh;




/**
 * A simple ssh client connection with private key.
 *
 * @author Robert Sandell &lt;robert.sandell@sonyericsson.com&gt;
 */
public class SshConnectionImpl implements SshConnection {

    private static final Logger logger = LoggerFactory.getLogger(SshConnectionImpl.class);
    /**
     * Keep-alive interval [msec]
     */
    private static final int ALIVE_INTERVAL = 30 * 1000;
    /**
     * Time to wait for the channel to close [msec]
     */
    private static final int CLOSURE_WAIT_TIMEOUT = 200;
    /**
     * Time to check for channel to close [msec]
     */
    private static final int CLOSURE_WAIT_INTERVAL = 50;
    /**
     * SSH Command to open an "exec channel".
     */
    protected static final String CMD_EXEC = "exec";
    /**
     * The str length of "://" used for proxy parsing.
     */
    protected static final int PROTO_HOST_DELIM_LENGTH = 3;
    private JSch client;
    private Session connectSession;
    private String host;
    private int port;
    private String proxy;
    private Authentication authentication;
    private AuthenticationUpdater updater;
    private int connectionTimeout;

    //CS IGNORE RedundantThrows FOR NEXT 30 LINES. REASON: Informative

    /**
     * Creates and opens a SshConnection.
     *
     * @param host           the host to connect to.
     * @param port           the port.
     * @param authentication the authentication-info
     */
    protected SshConnectionImpl(String host, int port,
                                Authentication authentication) {
// Path: src/main/java/com/sonymobile/tools/gerrit/gerritevents/GerritDefaultValues.java
// public final class GerritDefaultValues {
// 
//     /**
//      * Default private constructor to hinder instantiation.
//      */
//     private GerritDefaultValues() {
// 
//     }
//     /**
//      * The default gerrit name.
//      */
//     public static final String DEFAULT_GERRIT_NAME = "";
//     /**
//      * The default gerrit hostname.
//      */
//     public static final String DEFAULT_GERRIT_HOSTNAME = "";
//     /**
//      * The default gerrit front end url.
//      */
//     public static final String DEFAULT_GERRIT_FRONT_END_URL = "";
//     /**
//      * The default ssh port for the gerrit server.
//      */
//     public static final int DEFAULT_GERRIT_SSH_PORT = 29418;
//     /**
//      * The default scheme for the gerrit server.
//      */
//     public static final String DEFAULT_GERRIT_SCHEME = "ssh";
//     /**
//      * The default gerrit proxy.
//      */
//     public static final String DEFAULT_GERRIT_PROXY = "";
//     /**
//      * The default gerrit ssh connection timeout.
//      */
//     public static final int DEFAULT_GERRIT_SSH_CONNECTION_TIMEOUT = 0;
// 
//     /**
//      * The default key-file to use when authenticating to the gerrit server.
//      */
//     public static final File DEFAULT_GERRIT_AUTH_KEY_FILE = new File(new File(System.getProperty("user.home"), ".ssh"),
//                                                               "id_rsa");
//     /**
//      * The default password for the private key-file.
//      */
//     public static final String DEFAULT_GERRIT_AUTH_KEY_FILE_PASSWORD = null;
//     /**
//      * The default username to use when authenticating to the gerrit server.
//      */
//     public static final String DEFAULT_GERRIT_USERNAME = "";
//     /**
//      * The default nr of event worker threads.
//      */
//     public static final int DEFAULT_NR_OF_RECEIVING_WORKER_THREADS = 3;
//     /**
//      * The default keep alive time for receiving threads in seconds.
//      */
//     public static final int DEFAULT_RECEIVE_THREAD_KEEP_ALIVE_TIME = 1200;
//     /**
//      * The minimum keep alive time for receiving threads in seconds.
//      */
//     public static final int MIN_RECEIVE_THREAD_KEEP_ALIVE_TIME = 10;
//     /**
//      * The default nr of worker threads that sends approvals/review commands.
//      */
//     public static final int DEFAULT_NR_OF_SENDING_WORKER_THREADS = 1;
//     /**
//      * The default build schedule delay.
//      */
//     public static final int DEFAULT_BUILD_SCHEDULE_DELAY = 3;
//     /**
//      * The default refresh interval for the Dynamic Trigger Configuration.
//      */
//     public static final int DEFAULT_DYNAMIC_CONFIG_REFRESH_INTERVAL = 30;
// 
//     /**
//      * The minimum refresh interval for dynamic configuration.
//      */
//     public static final int MINIMUM_DYNAMIC_CONFIG_REFRESH_INTERVAL = 5;
// }


// Path: src/main/java/com/sonymobile/tools/gerrit/gerritevents/ssh/SshConnectionImpl.java
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.HostKeyRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.ProxyHTTP;
import com.jcraft.jsch.ProxySOCKS5;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import com.sonymobile.tools.gerrit.gerritevents.GerritDefaultValues;

/*
 * The MIT License
 *
 * Copyright 2011 Sony Ericsson Mobile Communications. All rights reserved.
 * Copyright 2014 Sony Mobile Communications AB. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.sonymobile.tools.gerrit.gerritevents.ssh;




/**
 * A simple ssh client connection with private key.
 *
 * @author Robert Sandell &lt;robert.sandell@sonyericsson.com&gt;
 */
public class SshConnectionImpl implements SshConnection {

    private static final Logger logger = LoggerFactory.getLogger(SshConnectionImpl.class);
    /**
     * Keep-alive interval [msec]
     */
    private static final int ALIVE_INTERVAL = 30 * 1000;
    /**
     * Time to wait for the channel to close [msec]
     */
    private static final int CLOSURE_WAIT_TIMEOUT = 200;
    /**
     * Time to check for channel to close [msec]
     */
    private static final int CLOSURE_WAIT_INTERVAL = 50;
    /**
     * SSH Command to open an "exec channel".
     */
    protected static final String CMD_EXEC = "exec";
    /**
     * The str length of "://" used for proxy parsing.
     */
    protected static final int PROTO_HOST_DELIM_LENGTH = 3;
    private JSch client;
    private Session connectSession;
    private String host;
    private int port;
    private String proxy;
    private Authentication authentication;
    private AuthenticationUpdater updater;
    private int connectionTimeout;

    //CS IGNORE RedundantThrows FOR NEXT 30 LINES. REASON: Informative

    /**
     * Creates and opens a SshConnection.
     *
     * @param host           the host to connect to.
     * @param port           the port.
     * @param authentication the authentication-info
     */
    protected SshConnectionImpl(String host, int port,
                                Authentication authentication) {
        this(host, port, GerritDefaultValues.DEFAULT_GERRIT_PROXY, authentication, null,