/*
 * @(#)Nntps.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.nntpssh;

import com.jscape.inet.ipclientssh.IpClientSsh;
import com.jscape.inet.nntp.Nntp;
import com.jscape.inet.nntp.NntpException;
import com.jscape.inet.ssh.util.SshParameters;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * Implements the basic functionality of a NNTP client tunnelling data through a secure SSH connection.
 * <P>
 * Example Usage:
 * <P>
 * <pre>
 * //
 * String sshHostname = "news.myserver.com";
 * String sshUsername = "jsmith";
 * String sshPassword = "secret";
 *
 * // create new SshParameters instance
 * SshParameters sshParams = new SshParameters(sshHostname,sshUsername,sshPassword);
 *
 * // create new NntpSsh instance
 * NntpSsh nntp = new NntpSsh(sshParams,"news.myserver.com");
 *
 * // establish connection and read headers
 * try
 * {
 *   nntp.connect();
 *   nntp.setNewsgroup("comp.lang.java.programmer");
 *   // get all headers and print out subject
 *   Enumeration headers = nntp.getArticleHeaders();
 *   while(headers.hasMoreElements())
 *   {
 *     NntpArticleHeader header = (NntpArticleHeader)headers.nextElement();
 *     System.out.println(header.getSubject());
 *   }
 *   // disconnect
 *   nntp.disconnect();
 * }
 * catch(Exception e)
 * {
 *   System.out.println(e);
 * }
 * </pre>
 * </p>
 */
public class NntpSsh
        extends Nntp {

    private SshParameters sshParameters;
    private IpClientSsh sshClient;

    /**
     * Creates a new NntpSsh instance.
     */
    public NntpSsh() {
        super();
    }

    /**
     * Creates a new NntpSsh instance.
     *
     * @param sshParameters the SSH parameters used in establishing a secure connection
     * @param hostname      the hostname of NNTP server
     */
    public NntpSsh(SshParameters sshParameters, String hostname) {
        super(hostname);
        this.sshParameters = sshParameters;
    }

    /**
     * Connects to NNTP server tunnelling all data through SSH server.
     *
     * @throws NntpException if I/O or NNTP related error occurs
     */
    public void connect()
            throws NntpException {
        try {
            sshClient = new IpClientSsh(sshParameters, hostname, port, timeout);
            sshClient.connect();

            reader =
                    new BufferedReader(
                            new InputStreamReader(sshClient.getInputStream()));
            writer = new BufferedOutputStream(sshClient.getOutputStream());

            String response = reader.readLine();
            debug(response);

            if (code(response) >= 400) {
                // connection success but the server
                // may have chosen not to allow us access
                throw new NntpException(message(response));
            }

            // volunteer authentication, this may help in
            // obtaining valid posting permissions
            if (username != null) {
                authenticate(username, password);
            }

            try {
                //send(MODE, "READER");
                issueCommand("MODE READER");
            } catch (Exception ez) {
                ez.printStackTrace();
            }
            this.fireNntpConnected();
        } catch (Exception e) {
            throw new NntpException(e.getMessage(), e);
        }
    }

    /**
     * Disconnects from NNTP server and closes tunnel with SSH server.
     */
    public void disconnect() {
        synchronized (this) {
            try {
                sshClient.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
            writer = null;
            reader = null;
            serverResponse.removeAllElements();
            this.fireNntpDisconnected();
        }

    }

    /**
     * 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;
    }
}
