/**
 * 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.geronimo.javamail.store.pop3.connection;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

import javax.mail.MessagingException;
import javax.mail.internet.InternetHeaders;

import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseStream;
import org.apache.geronimo.javamail.store.pop3.POP3Constants;
import org.apache.geronimo.javamail.util.CommandFailedException;
import org.apache.geronimo.javamail.util.InvalidCommandException;
import org.apache.geronimo.javamail.util.MIMEInputReader;
import org.apache.geronimo.javamail.util.MailConnection;
import org.apache.geronimo.javamail.util.ProtocolProperties;
import org.apache.geronimo.mail.util.Base64;
import org.apache.geronimo.mail.util.Hex;

/**
 * Simple implementation of POP3 transport.
 *
 * @version $Rev$ $Date$
 */
public class POP3Connection extends MailConnection implements POP3Constants {

    static final protected String MAIL_APOP_ENABLED = "apop.enable";
    static final protected String MAIL_AUTH_ENABLED = "auth.enable";
    static final protected String MAIL_RESET_QUIT = "rsetbeforequit";
    static final protected String MAIL_DISABLE_TOP = "disabletop";
    //static final protected String MAIL_FORGET_TOP = "forgettopheaders"; //TODO forgettopheaders

    // the initial greeting string, which might be required for APOP authentication.
    protected String greeting;
    // is use of the AUTH command enabled
    protected boolean authEnabled;
    // is use of APOP command enabled
    protected boolean apopEnabled;
    // input reader wrapped around the socket input stream
    protected BufferedReader reader;
    // output writer wrapped around the socket output stream.
    protected PrintWriter writer;
    // this connection was closed unexpectedly
    protected boolean closed;
    // indicates whether this connection is currently logged in.  Once
    // we send a QUIT, we're finished.
    protected boolean loggedIn;
    // indicates whether we need to avoid using the TOP command
    // when retrieving headers
    protected boolean topDisabled = false;
    // is TLS enabled on our part?
    protected boolean useTLS = false;
    // is TLS required on our part?
    protected boolean requireTLS = false;

    /**
     * Normal constructor for an POP3Connection() object.
     *
     * @param props  The protocol properties abstraction containing our
     *               property modifiers.
     */
    public POP3Connection(ProtocolProperties props) {
        super(props);

        // get our login properties flags
        authEnabled = props.getBooleanProperty(MAIL_AUTH_ENABLED, false);
        apopEnabled = props.getBooleanProperty(MAIL_APOP_ENABLED, false);
        topDisabled = props.getBooleanProperty(MAIL_DISABLE_TOP, false);
        // and also check for TLS enablement.
        useTLS = props.getBooleanProperty(MAIL_STARTTLS_ENABLE, false);
        // and also check if TLS is required.
        requireTLS = props.getBooleanProperty(MAIL_STARTTLS_REQUIRED, false);
       
    }


    /**
     * Connect to the server and do the initial handshaking.
     *
     * @exception MessagingException
     */
    public boolean protocolConnect(String host, int port, String authid, String realm, String username, String password) throws MessagingException {
        this.serverHost = host;
        this.serverPort = port;
        this.realm = realm;
        this.authid = authid;
        this.username = username;
        this.password = password;

        try {
            // create socket and connect to server.
            getConnection();
            // consume the welcome line
            getWelcome();
            
            // if we're not already using an SSL connection, and we have permission to issue STARTTLS or its even required
            // try to setup a SSL connection
            if (!sslConnection && (useTLS || requireTLS)) {
                
                    // tell the server of our intention to start a TLS session
                    POP3Response starttlsResponse = null;
                    try {
                        starttlsResponse = sendCommand("STLS");
                    } catch (CommandFailedException e) {
                       
                    }
                    
                    //if the server does not support TLS check if its required.
                    //If true then throw an error, if not establish a non SSL connection
                    if(requireTLS && (starttlsResponse == null || starttlsResponse.isError())) {
                        throw new MessagingException("Server doesn't support required transport level security");
                    } else if(starttlsResponse != null && starttlsResponse.getStatus() == POP3Response.OK) {
                     // The connection is then handled by the superclass level.
                        getConnectedTLSSocket();
                    } else {
                        if (debug) {
                            debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
                        }
                    }
            }
            
            getConnection();
            
            // go login with the server
            if (login())
            {
                loggedIn = true;
                return true;
            }
            return false;
        } catch (IOException e) {
            if (debug) {
                debugOut("I/O exception establishing connection", e);
            }
            throw new MessagingException("Connection error", e);
        }
    }


    /**
     * Create a transport connection object and connect it to the
     * target server.
     *
     * @exception MessagingException
     */
    protected void getConnection() throws MessagingException
    {
        try {
            // do all of the non-protocol specific set up.  This will get our socket established
            // and ready use.
            super.getConnection();
        } catch (IOException e) {
            throw new MessagingException("Unable to obtain a connection to the POP3 server", e);
        }

        // The POP3 protocol is inherently a string-based protocol, so we get
        // string readers/writers for the connection streams.  Note that we explicitly
        // set the encoding to ensure that an inappropriate native encoding is not picked up.
        try {
            reader = new BufferedReader(new InputStreamReader(inputStream, "ISO8859-1"));
            writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
        }
    }

    protected void getWelcome() throws IOException {
        // just read the line and consume it.  If debug is
        // enabled, there I/O stream will be traced
        greeting = reader.readLine();
    }

    public String toString() {
        return "POP3Connection host: " + serverHost + " port: " + serverPort;
    }


    /**
     * Close the connection.  On completion, we'll be disconnected from
     * the server and unable to send more data.
     *
     * @exception MessagingException
     */
    public void close() throws MessagingException {
        // if we're already closed, get outta here.
        if (socket == null) {
            return;
        }
        try {
            // say goodbye
            logout();
        } finally {
            // and close up the connection.  We do this in a finally block to make sure the connection
            // is shut down even if quit gets an error.
            closeServerConnection();
            // get rid of our response processor too.
            reader = null;
            writer = null;
        }
    }


    /**
     * Tag this connection as having been closed by the
     * server.  This will not be returned to the
     * connection pool.
     */
    public void setClosed() {
        closed = true;
    }

    /**
     * Test if the connection has been forcibly closed.
     *
     * @return True if the server disconnected the connection.
     */
    public boolean isClosed() {
        return closed;
    }

    protected POP3Response sendCommand(String cmd) throws MessagingException {
        return sendCommand(cmd, false);
    }

    protected POP3Response sendMultiLineCommand(String cmd) throws MessagingException {
        return sendCommand(cmd, true);
    }

    protected synchronized POP3Response sendCommand(String cmd, boolean multiLine) throws MessagingException {
        if (socket.isConnected()) {
            {
                // NOTE:  We don't use println() because it uses the platform concept of a newline rather
                // than using CRLF, which is required by the POP3 protocol.
                writer.write(cmd);
                writer.write("\r\n");
                writer.flush();

                POP3Response response = buildResponse(multiLine);
                if (response.isError()) {
                    throw new CommandFailedException("Error issuing POP3 command: " + cmd);
                }
                return response;
            }
        }
        throw new MessagingException("Connection to Mail Server is lost, connection " + this.toString());
    }

    /**
     * Build a POP3Response item from the response stream.
     *
     * @param isMultiLineResponse
     *               If true, this command is expecting multiple lines back from the server.
     *
     * @return A POP3Response item with all of the command response data.
     * @exception MessagingException
     */
    protected POP3Response buildResponse(boolean isMultiLineResponse) throws MessagingException {
        int status = ERR;
        byte[] data = null;

        String line;
        //MIMEInputReader source = new MIMEInputReader(reader); //TODO unused

        try {
            line = reader.readLine();
        } catch (IOException e) {
            throw new MessagingException("Error in receving response");
        }

        if (line == null || line.trim().equals("")) {
            throw new MessagingException("Empty Response");
        }

        if (line.startsWith("+OK")) {
            status = OK;
            line = removeStatusField(line);
            if (isMultiLineResponse) {
                data = getMultiLineResponse();
            }
        } else if (line.startsWith("-ERR")) {
            status = ERR;
            line = removeStatusField(line);
        }else if (line.startsWith("+")) {
        	status = CHALLENGE;
        	line = removeStatusField(line);
        	if (isMultiLineResponse) {
        		data = getMultiLineResponse();
        	}
        } else {
            throw new MessagingException("Unexpected response: " + line);
        }
        return new POP3Response(status, line, data);
    }

    private static String removeStatusField(String line) {
        return line.substring(line.indexOf(SPACE) + 1);
    }

    /**
     * This could be a multiline response
     */
    private byte[] getMultiLineResponse() throws MessagingException {

        MIMEInputReader source = new MIMEInputReader(reader);

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // it's more efficient to do this a buffer at a time.
        // the MIMEInputReader takes care of the byte-stuffing and
        // ".\r\n" input terminator for us.
        try {
            OutputStreamWriter outWriter = new OutputStreamWriter(out, "ISO8859-1");
            char buffer[] = new char[500];
            try {
                int charsRead = -1;
                while ((charsRead = source.read(buffer)) >= 0) {
                    outWriter.write(buffer, 0, charsRead);
                }
                outWriter.flush();
            } catch (IOException e) {
                throw new MessagingException("Error processing a multi-line response", e);
            }
        } catch (UnsupportedEncodingException e) {
        }
        return out.toByteArray();
    }


    /**
     * Retrieve the raw message content from the POP3
     * server.  This is all of the message data, including
     * the header.
     *
     * @param sequenceNumber
     *               The message sequence number.
     *
     * @return A byte array containing all of the message data.
     * @exception MessagingException
     */
    public byte[] retrieveMessageData(int sequenceNumber) throws MessagingException {
        POP3Response msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
        // we want the data directly in this case.
        return msgResponse.getData();
    }

    /**
     * Retrieve the message header information for a given
     * message, returned as an input stream suitable
     * for loading the message data.
     *
     * @param sequenceNumber
     *               The server sequence number for the message.
     *
     * @return An inputstream that can be used to read the message
     *         data.
     * @exception MessagingException
     */
    public ByteArrayInputStream retrieveMessageHeaders(int sequenceNumber) throws MessagingException {
        POP3Response msgResponse;

        // some POP3 servers don't correctly implement TOP, so this can be disabled.  If
        // we can't use TOP, then use RETR and retrieve everything.  We can just hand back
        // the stream, as the header loading routine will stop at the first
        // null line.
        if (topDisabled) {
            msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
        }
        else {
            msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0");
        }

        // just load the returned message data as a set of headers
        return msgResponse.getContentStream();
    }

    /**
     * Retrieve the total message size from the mail
     * server.  This is the size of the headers plus
     * the size of the message content.
     *
     * @param sequenceNumber
     *               The message sequence number.
     *
     * @return The full size of the message.
     * @exception MessagingException
     */
    public int retrieveMessageSize(int sequenceNumber) throws MessagingException {
        POP3Response msgResponse = sendCommand("LIST " + sequenceNumber);
        // Convert this into the parsed response type we need.
        POP3ListResponse list = new POP3ListResponse(msgResponse);
        // this returns the total message size
        return list.getSize();
    }

    /**
     * Retrieve the mail drop status information.
     *
     * @return An object representing the returned mail drop status.
     * @exception MessagingException
     */
    public POP3StatusResponse retrieveMailboxStatus() throws MessagingException {
        // issue the STAT command and return this into a status response
        return new POP3StatusResponse(sendCommand("STAT"));
    }


    /**
     * Retrieve the UID for an individual message.
     *
     * @param sequenceNumber
     *               The target message sequence number.
     *
     * @return The string UID maintained by the server.
     * @exception MessagingException
     */
    public String retrieveMessageUid(int sequenceNumber) throws MessagingException {
        POP3Response msgResponse = sendCommand("UIDL " + sequenceNumber);

        String message = msgResponse.getFirstLine();
        // the UID is everything after the blank separating the message number and the UID.
        // there's not supposed to be anything else on the message, but trim it of whitespace
        // just to be on the safe side.
        return message.substring(message.indexOf(' ') + 1).trim();
    }


    /**
     * Delete a single message from the mail server.
     *
     * @param sequenceNumber
     *               The sequence number of the message to delete.
     *
     * @exception MessagingException
     */
    public void deleteMessage(int sequenceNumber) throws MessagingException {
        // just issue the command...we ignore the command response
        sendCommand("DELE " + sequenceNumber);
    }

    /**
     * Logout from the mail server.  This sends a QUIT
     * command, which will likely sever the mail connection.
     *
     * @exception MessagingException
     */
    public void logout() throws MessagingException {
        // we may have already sent the QUIT command
        if (!loggedIn) {
            return;
        }
        // just issue the command...we ignore the command response
        sendCommand("QUIT");
        loggedIn = false;
    }

    /**
     * Perform a reset on the mail server.
     *
     * @exception MessagingException
     */
    public void reset() throws MessagingException {
        // some mail servers mark retrieved messages for deletion
        // automatically.  This will reset the read flags before
        // we go through normal cleanup.
        if (props.getBooleanProperty(MAIL_RESET_QUIT, false)) {
            // just send an RSET command first
            sendCommand("RSET");
        }
    }

    /**
     * Ping the mail server to see if we still have an active connection.
     *
     * @exception MessagingException thrown if we do not have an active connection.
     */
    public void pingServer() throws MessagingException {
        // just issue the command...we ignore the command response
        sendCommand("NOOP");
    }

    /**
     * Login to the mail server, using whichever method is
     * configured.  This will try multiple methods, if allowed,
     * in decreasing levels of security.
     *
     * @return true if the login was successful.
     * @exception MessagingException
     */
    public synchronized boolean login() throws MessagingException {
        // permitted to use the AUTH command?
        if (authEnabled) {
            try {
                // go do the SASL thing
                return processSaslAuthentication();
            } catch (MessagingException e) {
                // Any error here means fall back to the next mechanism
            }
        }

        if (apopEnabled) {
            try {
                // go do the SASL thing
                return processAPOPAuthentication();
            } catch (MessagingException e) {
                // Any error here means fall back to the next mechanism
            }
        }

        try {
            // do the tried and true login processing.
            return processLogin();
        } catch (MessagingException e) {
        }
        // everything failed...can't get in
        return false;
    }


    /**
     * Process a basic LOGIN operation, using the
     * plain test USER/PASS command combo.
     *
     * @return true if we logged successfully.
     * @exception MessagingException
     */
    public boolean processLogin() throws MessagingException {
        // start by sending the USER command, followed by
        // the PASS command
        sendCommand("USER " + username);
        sendCommand("PASS " + password);
        return true;       // we're in
    }

    /**
     * Process logging in using the APOP command.  Only
     * works on servers that give a timestamp value
     * in the welcome response.
     *
     * @return true if the login was accepted.
     * @exception MessagingException
     */
    public boolean processAPOPAuthentication() throws MessagingException {
        int timeStart = greeting.indexOf('<');
        // if we didn't get an APOP challenge on the greeting, throw an exception
        // the main login processor will swallow that and fall back to the next
        // mechanism
        if (timeStart == -1) {
            throw new MessagingException("POP3 Server does not support APOP");
        }
        int timeEnd = greeting.indexOf('>');
        String timeStamp = greeting.substring(timeStart, timeEnd + 1);

        // we create the digest password using the timestamp value sent to use
        // concatenated with the password.
        String digestPassword = timeStamp + password;

        byte[] digest;

        try {
            // create a digest value from the password.
            MessageDigest md = MessageDigest.getInstance("MD5");
            digest = md.digest(digestPassword.getBytes("iso-8859-1"));
        } catch (NoSuchAlgorithmException e) {
            // this shouldn't happen, but if it does, we'll just try a plain
            // login.
            throw new MessagingException("Unable to create MD5 digest", e);
        } catch (UnsupportedEncodingException e) {
            // this shouldn't happen, but if it does, we'll just try a plain
            // login.
            throw new MessagingException("Unable to create MD5 digest", e);
        }
        // this will throw an exception if it gives an error failure
        sendCommand("APOP " + username + " " + new String(Hex.encode(digest)));
        // no exception, we must have passed
        return true;
    }


    /**
     * Process SASL-type authentication.
     *
     * @return Returns true if the server support a SASL authentication mechanism and
     *         accepted reponse challenges.
     * @exception MessagingException
     */
    protected boolean processSaslAuthentication() throws MessagingException {
        // if unable to get an appropriate authenticator, just fail it.
        ClientAuthenticator authenticator = getSaslAuthenticator();
        if (authenticator == null) {
            throw new MessagingException("Unable to obtain SASL authenticator");
        }

        // go process the login.
        return processLogin(authenticator);
    }

    /**
     * Attempt to retrieve a SASL authenticator for this
     * protocol.
     *
     * @return A SASL authenticator, or null if a suitable one
     *         was not located.
     */
    protected ClientAuthenticator getSaslAuthenticator() {
        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
    }


    /**
     * Process a login using the provided authenticator object.
     *
     * NB:  This method is synchronized because we have a multi-step process going on
     * here.  No other commands should be sent to the server until we complete.
     *
     * @return Returns true if the server support a SASL authentication mechanism and
     * accepted reponse challenges.
     * @exception MessagingException
     */
    protected synchronized boolean processLogin(ClientAuthenticator authenticator) throws MessagingException {
        if (debug) {
            debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
        }

        POP3Response response = sendCommand("AUTH " + authenticator.getMechanismName());

        // now process the challenge sequence.  We get a continuation response back for each stage of the
        // authentication, and finally an OK when everything passes muster.
        while (true) {
            // this should be a continuation reply, if things are still good.
            if (response.isChallenge()) {
                // we're passed back a challenge value, Base64 encoded.
                byte[] challenge = response.decodeChallengeResponse();

                try {
                    String responseString = new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII");

                    // have the authenticator evaluate and send back the encoded response.
                    response = sendCommand(responseString);
                } catch (UnsupportedEncodingException ex) {
                }
            }
            else {
                // there are only two choices here, OK or a continuation.  OK means
                // we've passed muster and are in.
                return true;
            }
        }
    }


    /**
     * Merge the configured SASL mechanisms with the capabilities that the
     * server has indicated it supports, returning a merged list that can
     * be used for selecting a mechanism.
     *
     * @return A List representing the intersection of the configured list and the
     *         capabilities list.
     */
    protected List selectSaslMechanisms() {
        // just return the set that have been explicity permitted
        return getSaslMechanisms();
    }
}

