/**
 * 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.imap;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.mail.AuthenticationFailedException;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Quota;
import javax.mail.QuotaAwareStore;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.event.StoreEvent; 

import org.apache.geronimo.javamail.store.imap.connection.IMAPConnection; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPConnectionPool; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPOkResponse; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespaceResponse; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPNamespace; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPServerStatusResponse; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponse; 
import org.apache.geronimo.javamail.store.imap.connection.IMAPUntaggedResponseHandler; 
import org.apache.geronimo.javamail.util.ProtocolProperties;

/**
 * IMAP implementation of javax.mail.Store
 * POP protocol spec is implemented in
 * org.apache.geronimo.javamail.store.pop3.IMAPConnection
 *
 * @version $Rev: 707037 $ $Date: 2008-10-22 07:34:53 -0400 (Wed, 22 Oct 2008) $
 */

public class IMAPStore extends Store implements QuotaAwareStore, IMAPUntaggedResponseHandler {
    // the default connection ports for secure and non-secure variations
    protected static final int DEFAULT_IMAP_PORT = 143;
    protected static final int DEFAULT_IMAP_SSL_PORT = 993;
    
    protected static final String MAIL_STATUS_TIMEOUT = "statuscacheimeout";
    protected static final int DEFAULT_STATUS_TIMEOUT = 1000; 
    
    // our accessor for protocol properties and the holder of 
    // protocol-specific information 
    protected ProtocolProperties props; 

    // the connection pool we use for access 
	protected IMAPConnectionPool connectionPool;

    // the root folder
    protected IMAPRootFolder root;

    // the list of open folders (which also represents an open connection).
    protected List openFolders = new LinkedList();

    // our session provided debug output stream.
    protected PrintStream debugStream;
    // the debug flag 
    protected boolean debug; 
    // until we're connected, we're closed 
    boolean closedForBusiness = true; 
    // The timeout value for our status cache 
    long statusCacheTimeout = 0; 

    /**
     * Construct an IMAPStore item.
     *
     * @param session The owning javamail Session.
     * @param urlName The Store urlName, which can contain server target information.
     */
	public IMAPStore(Session session, URLName urlName) {
        // we're the imap protocol, our default connection port is 119, and don't use 
        // an SSL connection for the initial hookup 
		this(session, urlName, "imap", false, DEFAULT_IMAP_PORT);
	}
                                                          
    /**
     * Protected common constructor used by both the IMAPStore and the IMAPSSLStore
     * to initialize the Store instance. 
     * 
     * @param session  The Session we're attached to.
     * @param urlName  The urlName.
     * @param protocol The protocol name.
     * @param sslConnection
     *                 The sslConnection flag.
     * @param defaultPort
     *                 The default connection port.
     */
    protected IMAPStore(Session session, URLName urlName, String protocol, boolean sslConnection, int defaultPort) {
        super(session, urlName); 
        // create the protocol property holder.  This gives an abstraction over the different 
        // flavors of the protocol. 
        props = new ProtocolProperties(session, protocol, sslConnection, defaultPort); 
        
        // get the status timeout value for the folders. 
        statusCacheTimeout = props.getIntProperty(MAIL_STATUS_TIMEOUT, DEFAULT_STATUS_TIMEOUT);

        // get our debug settings
        debugStream = session.getDebugOut();
        debug = session.getDebug(); 
        
        // create a connection pool we can retrieve connections from 
        connectionPool = new IMAPConnectionPool(this, props); 
    }
    
    
    /**
     * Attempt the protocol-specific connection; subclasses should override this to establish
     * a connection in the appropriate manner.
     * 
     * This method should return true if the connection was established.
     * It may return false to cause the {@link #connect(String, int, String, String)} method to
     * reattempt the connection after trying to obtain user and password information from the user.
     * Alternatively it may throw a AuthenticatedFailedException to abandon the conection attempt.
     * 
     * @param host     The target host name of the service.
     * @param port     The connection port for the service.
     * @param user     The user name used for the connection.
     * @param password The password used for the connection.
     * 
     * @return true if a connection was established, false if there was authentication 
     *         error with the connection.
     * @throws AuthenticationFailedException
     *                if authentication fails
     * @throws MessagingException
     *                for other failures
     */
	protected synchronized boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {
        if (debug) {
            debugOut("Connecting to server " + host + ":" + port + " for user " + username);
        }

        // the connection pool handles all of the details here. 
        if (connectionPool.protocolConnect(host, port, username, password)) 
        {
            // the store is now open 
            closedForBusiness = false; 
            return true; 
        }
        return false; 
	}


    /**
     * Close this service and terminate its physical connection.
     * The default implementation simply calls setConnected(false) and then
     * sends a CLOSED event to all registered ConnectionListeners.
     * Subclasses overriding this method should still ensure it is closed; they should
     * also ensure that it is called if the connection is closed automatically, for
     * for example in a finalizer.
     *
     *@throws MessagingException if there were errors closing; the connection is still closed
     */
	public synchronized void close() throws MessagingException{
        // if already closed, nothing to do. 
        if (closedForBusiness) {
            return; 
        }
        
        // close the folders first, then shut down the Store. 
        closeOpenFolders();
        
        connectionPool.close(); 
        connectionPool = null; 

		// make sure we do the superclass close operation first so 
        // notification events get broadcast properly. 
		super.close();
	}


    /**
     * Return a Folder object that represents the root of the namespace for the current user.
     *
     * Note that in some store configurations (such as IMAP4) the root folder might
     * not be the INBOX folder.
     *
     * @return the root Folder
     * @throws MessagingException if there was a problem accessing the store
     */
	public Folder getDefaultFolder() throws MessagingException {
		checkConnectionStatus();
        // if no root yet, create a root folder instance. 
        if (root == null) {
            return new IMAPRootFolder(this);
        }
        return root;
	}

    /**
     * Return the Folder corresponding to the given name.
     * The folder might not physically exist; the {@link Folder#exists()} method can be used
     * to determine if it is real.
     * 
     * @param name   the name of the Folder to return
     * 
     * @return the corresponding folder
     * @throws MessagingException
     *                if there was a problem accessing the store
     */
	public Folder getFolder(String name) throws MessagingException {
        return getDefaultFolder().getFolder(name);
	}

    
    /**
     * Return the folder identified by the URLName; the URLName must refer to this Store.
     * Implementations may use the {@link URLName#getFile()} method to determined the folder name.
     * 
     * @param url
     * 
     * @return the corresponding folder
     * @throws MessagingException
     *                if there was a problem accessing the store
     */
	public Folder getFolder(URLName url) throws MessagingException {
        return getDefaultFolder().getFolder(url.getFile());
	}

    
    /**
     * Return the root folders of the personal namespace belonging to the current user.
     *
     * The default implementation simply returns an array containing the folder returned by {@link #getDefaultFolder()}.
     * @return the root folders of the user's peronal namespaces
     * @throws MessagingException if there was a problem accessing the store
     */
    public Folder[] getPersonalNamespaces() throws MessagingException {
        IMAPNamespaceResponse namespaces = getNamespaces(); 
        
        // if nothing is returned, then use the API-defined default for this 
        if (namespaces.personalNamespaces.size() == 0) {
            return super.getPersonalNamespaces(); 
        }
        
        // convert the list into an array of Folders. 
        return getNamespaceFolders(namespaces.personalNamespaces); 
    }
    
    
    /**
     * Return the root folders of the personal namespaces belonging to the supplied user.
     *
     * The default implementation simply returns an empty array.
     *
     * @param user the user whose namespaces should be returned
     * @return the root folders of the given user's peronal namespaces
     * @throws MessagingException if there was a problem accessing the store
     */
    public Folder[] getUserNamespaces(String user) throws MessagingException {
        IMAPNamespaceResponse namespaces = getNamespaces(); 
        
        // if nothing is returned, then use the API-defined default for this 
        if (namespaces.otherUserNamespaces == null || namespaces.otherUserNamespaces.isEmpty()) {
            return super.getUserNamespaces(user); 
        }
        
        // convert the list into an array of Folders. 
        return getNamespaceFolders(namespaces.otherUserNamespaces); 
    }

    
    /**
     * Return the root folders of namespaces that are intended to be shared between users.
     *
     * The default implementation simply returns an empty array.
     * @return the root folders of all shared namespaces
     * @throws MessagingException if there was a problem accessing the store
     */
    public Folder[] getSharedNamespaces() throws MessagingException {
        IMAPNamespaceResponse namespaces = getNamespaces(); 
        
        // if nothing is returned, then use the API-defined default for this 
        if (namespaces.sharedNamespaces == null || namespaces.sharedNamespaces.isEmpty()) {
            return super.getSharedNamespaces(); 
        }
        
        // convert the list into an array of Folders. 
        return getNamespaceFolders(namespaces.sharedNamespaces); 
    }
    
    
    /**
     * Get the quotas for the specified root element.
     *
     * @param root   The root name for the quota information.
     *
     * @return An array of Quota objects defined for the root.
     * @throws MessagingException if the quotas cannot be retrieved
     */
    public Quota[] getQuota(String root) throws javax.mail.MessagingException {
        // get our private connection for access 
        IMAPConnection connection = getStoreConnection(); 
        try {
            // request the namespace information from the server 
            return connection.fetchQuota(root); 
        } finally {
            releaseStoreConnection(connection); 
        }
    }

    /**
     * Set a quota item.  The root contained in the Quota item identifies
     * the quota target.
     *
     * @param quota  The source quota item.
     * @throws MessagingException if the quota cannot be set
     */
    public void setQuota(Quota quota) throws javax.mail.MessagingException {
        // get our private connection for access 
        IMAPConnection connection = getStoreConnection(); 
        try {
            // request the namespace information from the server 
            connection.setQuota(quota); 
        } finally {
            releaseStoreConnection(connection); 
        }
    }

    /**
     * Verify that the server is in a connected state before 
     * performing operations that required that status. 
     * 
     * @exception MessagingException
     */
	private void checkConnectionStatus() throws MessagingException {
        // we just check the connection status with the superclass.  This 
        // tells us we've gotten a connection.  We don't want to do the 
        // complete connection checks that require pinging the server. 
		if (!super.isConnected()){
		    throw new MessagingException("Not connected ");
	    }
	}


    /**
     * Test to see if we're still connected.  This will ping the server
     * to see if we're still alive.
     *
     * @return true if we have a live, active culture, false otherwise.
     */
    public synchronized boolean isConnected() {
        // check if we're in a presumed connected state.  If not, we don't really have a connection
        // to check on.
        if (!super.isConnected()) {
            return false;
        }
        
        try {
            IMAPConnection connection = getStoreConnection(); 
            try {
                // check with the connecition to see if it's still alive. 
                // we use a zero timeout value to force it to check. 
                return connection.isAlive(0);
            } finally {
                releaseStoreConnection(connection); 
            }
        } catch (MessagingException e) {
            return false; 
        }
        
    }

    /**
     * Internal debug output routine.
     *
     * @param value  The string value to output.
     */
    void debugOut(String message) {
        debugStream.println("IMAPStore DEBUG: " + message);
    }

    /**
     * Internal debugging routine for reporting exceptions.
     *
     * @param message A message associated with the exception context.
     * @param e       The received exception.
     */
    void debugOut(String message, Throwable e) {
        debugOut("Received exception -> " + message);
        debugOut("Exception message -> " + e.getMessage());
        e.printStackTrace(debugStream);
    }


    /**
     * Retrieve the server connection created by this store.
     *
     * @return The active connection object.
     */
    protected IMAPConnection getStoreConnection() throws MessagingException {
        return connectionPool.getStoreConnection(); 
    }
    
    protected void releaseStoreConnection(IMAPConnection connection) throws MessagingException {
        // This is a bit of a pain.  We need to delay processing of the 
        // unsolicited responses until after each user of the connection has 
        // finished processing the expected responses.  We need to do this because 
        // the unsolicited responses may include EXPUNGED messages.  The EXPUNGED 
        // messages will alter the message sequence numbers for the messages in the 
        // cache.  Processing the EXPUNGED messages too early will result in 
        // updates getting applied to the wrong message instances.  So, as a result, 
        // we delay that stage of the processing until all expected responses have 
        // been handled.  
        
        // process any pending messages before returning. 
        connection.processPendingResponses(); 
        // return this to the connectin pool 
        connectionPool.releaseStoreConnection(connection); 
    }
    
    synchronized IMAPConnection getFolderConnection(IMAPFolder folder) throws MessagingException {
        IMAPConnection connection = connectionPool.getFolderConnection(); 
        openFolders.add(folder);
        return connection; 
    }
    
    
    synchronized void releaseFolderConnection(IMAPFolder folder, IMAPConnection connection) throws MessagingException {
        openFolders.remove(folder); 
        // return this to the connectin pool 
        // NB:  It is assumed that the Folder has already triggered handling of 
        // unsolicited responses on this connection before returning it. 
        connectionPool.releaseFolderConnection(connection); 
    }


    /**
     * Retrieve the Session object this Store is operating under.
     *
     * @return The attached Session instance.
     */
    Session getSession() {
        return session;
    }
    
    /**
     * Close all open folders.  We have a small problem here with a race condition.  There's no safe, single
     * synchronization point for us to block creation of new folders while we're closing.  So we make a copy of
     * the folders list, close all of those folders, and keep repeating until we're done.
     */
    protected void closeOpenFolders() {
        // we're no longer accepting additional opens.  Any folders that open after this point will get an
        // exception trying to get a connection.
        closedForBusiness = true;

        while (true) {
            List folders = null;

            // grab our lock, copy the open folders reference, and null this out.  Once we see a null
            // open folders ref, we're done closing.
            synchronized(connectionPool) {
                folders = openFolders;
                openFolders = new LinkedList();
            }

            // null folder, we're done
            if (folders.isEmpty()) {
                return;
            }
            // now close each of the open folders.
            for (int i = 0; i < folders.size(); i++) {
                IMAPFolder folder = (IMAPFolder)folders.get(i);
                try {
                    folder.close(false);
                } catch (MessagingException e) {
                }
            }
        }
    }
    
    /**
     * Get the namespace information from the IMAP server.
     * 
     * @return An IMAPNamespaceResponse with the namespace information. 
     * @exception MessagingException
     */
    protected IMAPNamespaceResponse getNamespaces() throws MessagingException {
        // get our private connection for access 
        IMAPConnection connection = getStoreConnection(); 
        try {
            // request the namespace information from the server 
            return connection.getNamespaces(); 
        } finally {
            releaseStoreConnection(connection); 
        }
    }
    
    
    /**
     * Convert a List of IMAPNamespace definitions into an array of Folder 
     * instances. 
     * 
     * @param namespaces The namespace List
     * 
     * @return An array of the same size as the namespace list containing a Folder 
     *         instance for each defined namespace.
     * @exception MessagingException
     */
    protected Folder[] getNamespaceFolders(List namespaces) throws MessagingException {
        Folder[] folders = new Folder[namespaces.size()]; 
        
        // convert each of these to a Folder instance. 
        for (int i = 0; i < namespaces.size(); i++) {
            IMAPNamespace namespace = (IMAPNamespace)namespaces.get(i); 
            folders[i] = new IMAPNamespaceFolder(this, namespace); 
        }
        return folders; 
    }
    
    
    /**
     * Test if this connection has a given capability. 
     * 
     * @param capability The capability name.
     * 
     * @return true if this capability is in the list, false for a mismatch. 
     */
    public boolean hasCapability(String capability) {
        return connectionPool.hasCapability(capability); 
    }
    
    
    /**
     * Handle an unsolicited response from the server.  Most unsolicited responses 
     * are replies to specific commands sent to the server.  The remainder must 
     * be handled by the Store or the Folder using the connection.  These are 
     * critical to handle, as events such as expunged messages will alter the 
     * sequence numbers of the live messages.  We need to keep things in sync.
     * 
     * @param response The UntaggedResponse to process.
     * 
     * @return true if we handled this response and no further handling is required.  false
     *         means this one wasn't one of ours.
     */
    public boolean handleResponse(IMAPUntaggedResponse response) {
        // Some sort of ALERT response from the server?
        // we need to broadcast this to any of the listeners 
        if (response.isKeyword("ALERT")) {
            notifyStoreListeners(StoreEvent.ALERT, ((IMAPOkResponse)response).getMessage()); 
            return true; 
        }
        // potentially some sort of unsolicited OK notice.  This is also an event. 
        else if (response.isKeyword("OK")) {
            String message = ((IMAPOkResponse)response).getMessage(); 
            if (message.length() > 0) {
                notifyStoreListeners(StoreEvent.NOTICE, message); 
            }
            return true; 
        }
        // potentially some sort of unsolicited notice.  This is also an event. 
        else if (response.isKeyword("BAD") || response.isKeyword("NO")) {
            String message = ((IMAPServerStatusResponse)response).getMessage(); 
            if (message.length() > 0) {
                notifyStoreListeners(StoreEvent.NOTICE, message); 
            }
            return true; 
        }
        // this is a BYE response on our connection.  Folders should be handling the 
        // BYE events on their connections, so we should only be seeing this if 
        // it's on the store connection.  
        else if (response.isKeyword("BYE")) {
            // this is essentially a close event.  We need to clean everything up 
            try {
                close();                
            } catch (MessagingException e) {
            }
            return true; 
        }
        return false; 
    }
    
    /**
     * Finalizer to perform IMAPStore() cleanup when 
     * no longer in use. 
     * 
     * @exception Throwable
     */
    protected void finalize() throws Throwable {
        super.finalize(); 
        close(); 
    }
    
    /**
     * Retrieve the protocol properties for the Store. 
     * 
     * @return The protocol properties bundle. 
     */
    ProtocolProperties getProperties() {
        return props; 
    }
}
