/*
 * @(#)Pops.java
 *
 * Copyright (c) 2003 JSCAPE
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with JSCAPE.
 */
package com.jscape.inet.popssh;

import com.jscape.inet.ipclientssh.IpClientSsh;
import com.jscape.inet.pop.Pop;
import com.jscape.inet.pop.PopException;
import com.jscape.inet.ssh.util.SshParameters;

import java.io.BufferedInputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

/**
 * Implements the basic functionality of a POP3 client tunnelling all data through a secure SSH connection.<P>
 * Example Usage:
 * <p/>
 * <P>
 * <pre>
 * // connection parameters for SSH server
 * String sshHostname = "pop3.myserver.com";
 * String sshUsername = "jsmith";
 * String sshPassword = "secret";
 *
 * // create new SshParameters instance
 * SshParameters sshParams = new SshParameters(sshHostname,sshUsername,sshPassword);
 *
 * // new instance with SSH parameters, hostname, username and password
 * PopSsh pop = new PopSsh(sshParams, "pop3.myserver.com","jsmith","secret");
 * try
 * {
 *   // connect to POP3 server
 *   pop.connect();
 *    // get messages
 *   Enumeration e = pop.getMessages();
 *   while(e.hasMoreElements()) {
 *     EmailMessage em = (EmailMessage)e.nextElement();
 *   }
 *    // disconnect
 *   pop.disconnect();
 * }
 * catch(Exception e)
 * {
 *   System.out.println(e);
 * }
 * </pre>
 * </p>
 */
public class PopSsh
        extends Pop {

    private SshParameters sshParameters;
    private IpClientSsh sshClient;

    /**
     * Constructs a new Pop instance.
     */
    public PopSsh() {
        super();
    }

    /**
     * Constructs a new PopSsh instance. Sets hostname, username and password for
     * POP3 connection.
     *
     * @param hostname the hostname of POP3 server
     * @param username the username of POP3 user
     * @param password the password of POP3 user
     */
    public PopSsh(String hostname, String username, String password) {
        super(hostname, username, password);
    }

    /**
     * Constructs a new PopSsh instance. Sets hostname, username and password for
     * POP3 connection and parameters for connection to SSH server.
     *
     * @param hostname      the hostname of POP3 server
     * @param username      the username of POP3 user
     * @param password      the password of POP3 user
     * @param sshParameters the SSH parameters used in establishing a secure connection
     */
    public PopSsh(
            SshParameters sshParameters,
            String hostname,
            String username,
            String password) {
        super(hostname, username, password);
        this.sshParameters = sshParameters;
    }

    /**
     * Connects to POP3 server tunelling data through SSH server and performs login with POP3 server.
     *
     * @throws PopException if I/O or POP3 related error occurs
     */
    public PopSsh connect()
            throws PopException {
        try {
            sshClient = new IpClientSsh(sshParameters, hostname, port, timeout);
            sshClient.connect();
            in =
                    new BufferedInputStream(sshClient.getInputStream());
            out =
                    new PrintWriter(
                            new OutputStreamWriter(sshClient.getOutputStream()));

            // get POP3 banner
            String banner = readLine(in);
            debug(banner);

            this.authentication.apply(this, banner);

            this.firePopConnected();

            return this;
        } catch (Exception e) {
            throw new PopException(e.getMessage(), e);
        }
    }

    /**
     * Disconnects from POP3 server. Issues QUIT command to POP3 server and closes connection with SSH server.
     *
     * @throws PopException if I/O or POP3 related error occurs
     */
    public void disconnect()
            throws PopException {
        try {
            synchronized (this) {
                issueCommand("QUIT");
                sshClient.disconnect();
            }
        } catch (NullPointerException npe) {
            throw new PopException("POP client already disconnected");
        } catch (Exception e) {
            throw new PopException(e.getMessage(), e);
        } finally {
            out = null;
            in = null;
            this.firePopDisconnected();
        }
    }

    /**
     * Gets SSH parameters used in establishing connection with SSH server.
     *
     * @return the SSH parameters
     *
     * @see com.jscape.inet.ssh.util.SshParameters
     */
    public SshParameters getSshParameters() {
        return sshParameters;
    }

    /**
     * Sets SSH parameters used in establishing connection with SSH server.
     *
     * @param parameters the SSH parameters
     *
     * @see com.jscape.inet.ssh.util.SshParameters
     */
    public void setSshParameters(SshParameters parameters) {
        sshParameters = parameters;
    }
}
