/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Atsuhiko Yamanaka, JCraft,Inc. - initial API and implementation.
 *     IBM Corporation - ongoing maintenance
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.ssh2;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Enumeration;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
import org.eclipse.team.internal.ccvs.core.util.Util;

import com.jcraft.jsch.*;

class JSchSession {
	private static final int SSH_DEFAULT_PORT = 22;
	private static JSch jsch=new JSch();
	private static java.util.Hashtable pool = new java.util.Hashtable();

	private static String current_ssh_home = null;
	private static String current_pkeys = ""; //$NON-NLS-1$
    private final Session session;
    private final UserInfo prompter;
    private final ICVSRepositoryLocation location;

    protected static int getCVSTimeoutInMillis() {
        //return CVSProviderPlugin.getPlugin().getTimeout() * 1000;
    	// TODO Hard-code the timeout for now since Jsch doesn't respect CVS timeout
    	// See bug 92887
    	return 60000;
    }
    
	public static class SimpleSocketFactory implements SocketFactory {
		InputStream in = null;
		OutputStream out = null;
		public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
			Socket socket = null;
			socket = new Socket(host, port);
			return socket;
		}
		public InputStream getInputStream(Socket socket) throws IOException {
			if (in == null)
				in = socket.getInputStream();
			return in;
		}
		public OutputStream getOutputStream(Socket socket) throws IOException {
			if (out == null)
				out = socket.getOutputStream();
			return out;
		}
	}
	
	public static class ResponsiveSocketFacory extends SimpleSocketFactory {
		private IProgressMonitor monitor;
		public ResponsiveSocketFacory(IProgressMonitor monitor) {
			this.monitor = monitor;
		}
		public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
			Socket socket = null;
			socket = Util.createSocket(host, port, monitor);
			// Null out the monitor so we don't hold onto anything
			// (i.e. the SSH2 session will keep a handle to the socket factory around
			monitor = new NullProgressMonitor();
			// Set the socket timeout
			socket.setSoTimeout(getCVSTimeoutInMillis());
			return socket;
		}
	}
	
    /**
     * UserInfo wrapper class that will time how long each prompt takes
     */
    private static class UserInfoTimer implements UserInfo, UIKeyboardInteractive {

        private UserInfo wrappedInfo;
        private long startTime;
        private long endTime;
        private boolean prompting;
        
        public UserInfoTimer(UserInfo wrappedInfo) {
            this.wrappedInfo = wrappedInfo;
        }
        
        private synchronized void startTimer() {
            prompting = true;
            startTime = System.currentTimeMillis();
        }
        
        private synchronized void endTimer() {
            prompting = false;
            endTime = System.currentTimeMillis();
        }
        
        public long getLastDuration() {
            return Math.max(0, endTime-startTime);
        }
        
        public boolean hasPromptExceededTimeout() {
            if (!isPrompting()) {
                return getLastDuration() > getCVSTimeoutInMillis();
            }
            return false;
        }
        
        public String getPassphrase() {
            return wrappedInfo.getPassphrase();
        }

        public String getPassword() {
            return wrappedInfo.getPassword();
        }

        public boolean promptPassword(String arg0) {
            try {
                startTimer();
                return wrappedInfo.promptPassword(arg0);
            } finally {
                endTimer();
            }
        }

        public boolean promptPassphrase(String arg0) {
            try {
                startTimer();
                return wrappedInfo.promptPassphrase(arg0);
            } finally {
                endTimer();
            }
        }

        public boolean promptYesNo(String arg0) {
            try {
                startTimer();
                return wrappedInfo.promptYesNo(arg0);
            } finally {
                endTimer();
            }
        }

        public void showMessage(String arg0) {
        	if(arg0.length()!=0){
	            try {
	                startTimer();	                
	                wrappedInfo.showMessage(arg0);  
	            } finally {
	                endTimer();
	            }
        	}
        }

        public String[] promptKeyboardInteractive(String arg0, String arg1, String arg2, String[] arg3, boolean[] arg4) {
            try {
                startTimer();
                return ((UIKeyboardInteractive)wrappedInfo).promptKeyboardInteractive(arg0, arg1, arg2, arg3, arg4);
            } finally {
                endTimer();
            }
        }

        public boolean isPrompting() {
            return prompting;
        }
    }
    
	/**
	 * User information delegates to the IUserAuthenticator. This allows
	 * headless access to the connection method.
	 */
	private static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
		private String username;
		private String password;
		private String passphrase;
		private ICVSRepositoryLocation location;
		private IUserAuthenticator authenticator;
        private int attemptCount;
        private boolean passwordChanged;
		
		MyUserInfo(String username, String password, ICVSRepositoryLocation location) {
			this.location = location;
			this.username = username;
			this.password = password;
			ICVSRepositoryLocation _location=location;
			if(_location==null){
				String dummy=":extssh:dummy@dummy:/"; //$NON-NLS-1$
				try{
					_location=CVSRepositoryLocation.fromString(dummy);
				}
				catch(CVSException e){
				}
			}
			authenticator = _location.getUserAuthenticator();
			
		}
		public String getPassword() {
			return password;
		}
		public String getPassphrase() {
			return passphrase;
		}
		public boolean promptYesNo(String str) {
			int prompt = authenticator.prompt(
					location, 
					IUserAuthenticator.QUESTION, 
					CVSSSH2Messages.JSchSession_5,  
					str, 
					new int[] {IUserAuthenticator.YES_ID, IUserAuthenticator.NO_ID}, 
					0 //yes the default
					);
			return prompt == 0;
		}
		private String promptSecret(String message, boolean includeLocation) throws CVSException{
			final String[] _password = new String[1];
			IUserInfo info = new IUserInfo() {
				public String getUsername() {
					return username;
				}
				public boolean isUsernameMutable() {
					return false;
				}
				public void setPassword(String password) {
					_password[0] = password;
				}
				public void setUsername(String username) {
				}
			};
			try{
				authenticator.promptForUserInfo(includeLocation ? location : null, info,	message);
			}
			catch(OperationCanceledException e){
				_password[0]=null;
			}
			return _password[0];	
		}
		public boolean promptPassphrase(String message) {
			try{
				String _passphrase=promptSecret(message, false);
				if(_passphrase!=null){
				  passphrase=_passphrase;
				}
				return _passphrase!=null;
			}
			catch(CVSException e){
				return false;
			}
		}
		public boolean promptPassword(String message) {
			try{
				String _password=promptSecret(message, true);
				if(_password!=null){
					password=_password;
					// Cache the password with the repository location on the memory.
					if(location!=null)
						((CVSRepositoryLocation)location).setPassword(password);
				}
				return _password!=null;
			}
			catch(CVSException e){
				return false;
			}
		}
		public void showMessage(String message) {
    		authenticator.prompt(
    				location,
    				IUserAuthenticator.INFORMATION,
    				CVSSSH2Messages.JSchSession_5, 
    				message,
    				new int[] {IUserAuthenticator.OK_ID},
    				IUserAuthenticator.OK_ID
    				);
            
		}
        public String[] promptKeyboardInteractive(String destination,   
				String name,   
				String instruction,   
				String[] prompt,   
				boolean[] echo){
		    if (prompt.length == 0) {
		        // No need to prompt, just return an empty String array
		        return new String[0];
		    }
			try{
			    if (attemptCount == 0 && password != null && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
			        // Return the provided password the first time but always prompt on subsequent tries
			        attemptCount++;
			        return new String[] { password };
			    }
				String[] result=
					authenticator.promptForKeyboradInteractive(location,
																destination,   
																name,   	
																instruction,
																prompt,   
																echo);
                if (result == null) 
                    return null; // canceled
			    if (result.length == 1 && prompt.length == 1 && prompt[0].trim().equalsIgnoreCase("password:")) { //$NON-NLS-1$
			        password = result[0];
			        passwordChanged = true;
			    }
			    attemptCount++;
				return result;
			}
			catch(OperationCanceledException e){
				return null;
			}
			catch(CVSException e){
				return null;
			}
		}
		
        /**
         * Callback to indicate that a connection is about to be attempted
         */
        public void aboutToConnect() {
            attemptCount = 0;
            passwordChanged = false;
        }
        
        /**
         * Callback to indicate that a connection was made
         */
        public void connectionMade() {
            attemptCount = 0;
            if (passwordChanged && password != null && location != null) {
                // We were prompted for and returned a password so record it with the location
                location.setPassword(password);
            }
        }
	}

    public static boolean isAuthenticationFailure(JSchException ee) {
        return ee.getMessage().equals("Auth fail"); //$NON-NLS-1$
    }
    
    static JSchSession getSession(ICVSRepositoryLocation location, String username, String password, String hostname, int port, IProgressMonitor monitor) throws JSchException {

        if (port == ICVSRepositoryLocation.USE_DEFAULT_PORT)
            port = getPort(location);
        
		IPreferenceStore store = CVSSSH2Plugin.getDefault().getPreferenceStore();
		String ssh_home = store.getString(ISSHContants.KEY_SSH2HOME);
		String pkeys = store.getString(ISSHContants.KEY_PRIVATEKEY);

		try {
			if (current_ssh_home == null || !current_ssh_home.equals(ssh_home)) {
				loadKnownHosts();
				current_ssh_home = ssh_home;
			}

			if (ssh_home.length() == 0)
				ssh_home = CVSSSH2Plugin.SSH_HOME_DEFAULT;

			if (!current_pkeys.equals(pkeys)) {
				java.io.File file;
				String[] pkey = pkeys.split(","); //$NON-NLS-1$
				String[] _pkey = current_pkeys.split(","); //$NON-NLS-1$
				current_pkeys = ""; //$NON-NLS-1$
				for (int i = 0; i < pkey.length; i++) {
					file = new java.io.File(pkey[i]);
					if (!file.isAbsolute()) {
						file = new java.io.File(ssh_home, pkey[i]);
					}
					if (file.exists()) {
						boolean notyet = true;
						for (int j = 0; j < _pkey.length; j++) {
							if (pkey[i].equals(_pkey[j])) {
								notyet = false;
								break;
							}
						}
						if (notyet)
							jsch.addIdentity(file.getPath());
						if (current_pkeys.length() == 0) {
							current_pkeys = pkey[i];
						} else {
							current_pkeys += ("," + pkey[i]); //$NON-NLS-1$
						}
					}
				}
			}
		} catch (Exception e) {
		}
		

		String key = getPoolKey(username, hostname, port);

		try {
			JSchSession jschSession = (JSchSession) pool.get(key);
			if (jschSession != null && !jschSession.getSession().isConnected()) {
				pool.remove(key);
                jschSession = null;
			}

			if (jschSession == null) {
				boolean useProxy = CVSProviderPlugin.getPlugin().isUseProxy();
                Proxy proxy = null;
				if (useProxy) {
					String _type = CVSProviderPlugin.getPlugin().getProxyType();
					String _host = CVSProviderPlugin.getPlugin().getProxyHost();
					String _port = CVSProviderPlugin.getPlugin().getProxyPort();

					boolean useAuth = CVSProviderPlugin.getPlugin().isUseProxyAuth();
					String _user = ""; //$NON-NLS-1$
					String _pass = ""; //$NON-NLS-1$
					
					// Retrieve username and password from keyring.
					if(useAuth){
						_user=CVSProviderPlugin.getPlugin().getProxyUser();
						_pass=CVSProviderPlugin.getPlugin().getProxyPassword();
					}

					String proxyhost = _host + ":" + _port; //$NON-NLS-1$
					if (_type.equals(CVSProviderPlugin.PROXY_TYPE_HTTP)) {
						proxy = new ProxyHTTP(proxyhost);
						if (useAuth) {
							((ProxyHTTP) proxy).setUserPasswd(_user, _pass);
						}
					} else if (_type.equals(CVSProviderPlugin.PROXY_TYPE_SOCKS5)) {
						proxy = new ProxySOCKS5(proxyhost);
						if (useAuth) {
							((ProxySOCKS5) proxy).setUserPasswd(_user, _pass);
						}
					} else {
						proxy = null;
					}
				}

                MyUserInfo ui = new MyUserInfo(username, password, location);
                UserInfoTimer wrapperUI = new UserInfoTimer(ui);
                ui.aboutToConnect();
                
                Session session = null;
                try {
                    session = createSession(username, password, hostname, port, new JSchSession.ResponsiveSocketFacory(monitor), proxy, wrapperUI);
                } catch (JSchException e) {
                    if (isAuthenticationFailure(e) && wrapperUI.hasPromptExceededTimeout()) {
                        // Try again since the previous prompt may have obtained the proper credentials from the user
                        session = createSession(username, password, hostname, port, new JSchSession.ResponsiveSocketFacory(monitor), proxy, wrapperUI);
                    } else {
                        throw e;
                    }
                }
                ui.connectionMade();
                JSchSession schSession = new JSchSession(session, location, wrapperUI);
                pool.put(key, schSession);
                return schSession;
			} else {
                return jschSession;
            }
		} catch (JSchException e) {
			pool.remove(key);
			if(e.toString().indexOf("Auth cancel")!=-1){  //$NON-NLS-1$
				throw new OperationCanceledException();
			}
			throw e;
		}
	}

    private static Session createSession(String username, String password, String hostname, int port, SocketFactory socketFactory, Proxy proxy, UserInfo wrapperUI) throws JSchException {
        Session session = jsch.getSession(username, hostname, port);
        if (proxy != null) {
            session.setProxy(proxy);
        }
        session.setTimeout(getCVSTimeoutInMillis());
        session.setPassword(password);
        session.setUserInfo(wrapperUI);
        session.setSocketFactory(socketFactory);
        // This is where the server is contacted and authentication occurs
        try {
            session.connect();
        } catch (JSchException e) {
            if (session.isConnected())
                session.disconnect();
            throw e;
        }
        return session;
    }

    private static String getPoolKey(String username, String hostname, int port) {
        return username + "@" + hostname + ":" + port; //$NON-NLS-1$ //$NON-NLS-2$
    }

    private static String getPoolKey(ICVSRepositoryLocation location){
        return location.getUsername() + "@" + location.getHost() + ":" + getPort(location); //$NON-NLS-1$ //$NON-NLS-2$
    }

	private static int getPort(ICVSRepositoryLocation location) {
        int port = location.getPort();
        if (port == ICVSRepositoryLocation.USE_DEFAULT_PORT)
            port = SSH_DEFAULT_PORT;
        return port;
    }

    static void loadKnownHosts(){
		IPreferenceStore store = CVSSSH2Plugin.getDefault().getPreferenceStore();
		String ssh_home = store.getString(ISSHContants.KEY_SSH2HOME);

		if (ssh_home.length() == 0)
			ssh_home = CVSSSH2Plugin.SSH_HOME_DEFAULT;

		try {
		  java.io.File file;
		  file=new java.io.File(ssh_home, "known_hosts"); //$NON-NLS-1$
		  jsch.setKnownHosts(file.getPath());
		} catch (Exception e) {
		}
	}

	static void shutdown() {
		if (jsch != null && pool.size() > 0) {
			for (Enumeration e = pool.elements(); e.hasMoreElements(); ) {
                JSchSession session = (JSchSession) (e.nextElement());
				try {
					session.getSession().disconnect();
				} catch (Exception ee) {
				}
			}
			pool.clear();
		}
	}
  static JSch getJSch(){
    return jsch;
  }
  
    private JSchSession(Session session, ICVSRepositoryLocation location, UserInfo prompter) {
        this.session = session;
        this.location = location;
        this.prompter = prompter;
    }

    public Session getSession() {
        return session;
    }

    public UserInfo getPrompter() {
        return prompter;
    }

    public boolean hasPromptExceededTimeout() {
        if (prompter instanceof UserInfoTimer) {
            UserInfoTimer timer = (UserInfoTimer) prompter;
            if (!timer.isPrompting()) {
                return timer.getLastDuration() > getCVSTimeoutInMillis();
            }
        }
        return false;
    }
    
    public void dispose() {
        if (session.isConnected()) {
            session.disconnect();
        }
        pool.remove(getPoolKey(location));
    }

}
