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

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;

import javax.mail.Flags;
import javax.mail.IllegalWriteException;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeMessage;

import org.apache.geronimo.javamail.transport.nntp.NNTPConnection;
import org.apache.geronimo.javamail.transport.nntp.NNTPReply;
import org.apache.geronimo.javamail.transport.nntp.StringListInputStream;

/**
 * NNTP implementation of javax.mail.internet.MimeMessage
 * 
 * Only the most basic information is given and Message objects created here is
 * a light-weight reference to the actual Message As per the JavaMail spec items
 * from the actual message will get filled up on demand
 * 
 * If some other items are obtained from the server as a result of one call,
 * then the other details are also processed and filled in. For ex if RETR is
 * called then header information will also be processed in addition to the
 * content
 * 
 * @version $Rev: 437941 $ $Date: 2006-08-28 23:56:02 -0400 (Mon, 28 Aug 2006) $
 */
public class NNTPMessage extends MimeMessage {
    // the server message identifer
    String messageID = null;

    // our attached session
    protected Session session;

    // the Store we're stored in (which manages the connection and other stuff).
    protected NNTPStore store;

    // our active connection.
    protected NNTPConnection connection;

    // used to force loading of headers
    protected boolean headersLoaded = false;

    // use to force content loading
    protected boolean contentLoaded = false;

    /**
     * Contruct an NNTPMessage instance.
     * 
     * @param folder
     *            The hosting folder for the message.
     * @param store
     *            The Store owning the article (and folder).
     * @param msgnum
     *            The article message number.
     * @param messageID
     *            The article messageID (as assigned by the server).
     * 
     * @exception MessagingException
     */
    NNTPMessage(NNTPFolder folder, NNTPStore store, int msgnum, String messageID) throws MessagingException {
        super(folder, msgnum);
        this.messageID = messageID;
        this.store = store;
        this.session = ((NNTPStore) store).getSession();
        // get the active connection from the store...all commands are sent
        // there
        this.connection = ((NNTPStore) store).getConnection();

        // get our flag set from the folder.
        flags = folder.getPermanentFlags();
        // now check our initial SEEN state and set the flags appropriately
        if (folder.isSeen(msgnum)) {
            flags.add(Flags.Flag.SEEN);
        } else {
            flags.remove(Flags.Flag.SEEN);
        }
    }

    /**
     * Retrieve the size of the message content. The content will be retrieved
     * from the server, if necessary.
     * 
     * @return The size of the content.
     * @exception MessagingException
     */
    public int getSize() throws MessagingException {
        // make sure we've retrieved the message content and continue with the
        // superclass version.
        loadContent();
        return super.getSize();
    }

    /**
     * Get a line count for the NNTP message. This is potentially stored in the
     * Lines article header. If not there, we return a default of -1.
     * 
     * @return The header line count estimate, or -1 if not retrieveable.
     * @exception MessagingException
     */
    public int getLineCount() throws MessagingException {
        String[] headers = getHeader("Lines");

        // hopefully, there's only a single one of these. No sensible way of
        // interpreting
        // multiples.
        if (headers.length == 1) {
            try {
                return Integer.parseInt(headers[0].trim());

            } catch (NumberFormatException e) {
                // ignore
            }
        }
        // dunno...and let them know I don't know.
        return -1;
    }

    /**
     * @see javax.mail.internet.MimeMessage#getContentStream()
     */
    protected InputStream getContentStream() throws MessagingException {
        // get the article information.
        loadArticle();
        return super.getContentStream();
    }

    /***************************************************************************
     * Following is a set of methods that deal with headers These methods are
     * just overrides on the superclass methods to allow lazy loading of the
     * header information.
     **************************************************************************/

    public String[] getHeader(String name) throws MessagingException {
        loadHeaders();
        return headers.getHeader(name);
    }

    public String getHeader(String name, String delimiter) throws MessagingException {
        loadHeaders();
        return headers.getHeader(name, delimiter);
    }

    public Enumeration getAllHeaders() throws MessagingException {
        loadHeaders();
        return headers.getAllHeaders();
    }

    public Enumeration getMatchingHeaders(String[] names) throws MessagingException {
        loadHeaders();
        return headers.getMatchingHeaders(names);
    }

    public Enumeration getNonMatchingHeaders(String[] names) throws MessagingException {
        loadHeaders();
        return headers.getNonMatchingHeaders(names);
    }

    public Enumeration getAllHeaderLines() throws MessagingException {
        loadHeaders();
        return headers.getAllHeaderLines();
    }

    public Enumeration getMatchingHeaderLines(String[] names) throws MessagingException {
        loadHeaders();
        return headers.getMatchingHeaderLines(names);
    }

    public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
        loadHeaders();
        return headers.getNonMatchingHeaderLines(names);
    }

    // the following are overrides for header modification methods. These
    // messages are read only,
    // so the headers cannot be modified.
    public void addHeader(String name, String value) throws MessagingException {
        throw new IllegalWriteException("NNTP messages are read-only");
    }

    public void setHeader(String name, String value) throws MessagingException {
        throw new IllegalWriteException("NNTP messages are read-only");
    }

    public void removeHeader(String name) throws MessagingException {
        throw new IllegalWriteException("NNTP messages are read-only");
    }

    public void addHeaderLine(String line) throws MessagingException {
        throw new IllegalWriteException("IMAP messages are read-only");
    }

    /**
     * We cannot modify these messages
     */
    public void saveChanges() throws MessagingException {
        throw new IllegalWriteException("NNTP messages are read-only");
    }

    /**
     * Retrieve the message headers from the NNTP server.
     * 
     * @exception MessagingException
     */
    public void loadHeaders() throws MessagingException {
        // don't retrieve if already loaded.
        if (headersLoaded) {
            return;
        }

        NNTPReply reply = connection.sendCommand("HEAD " + messageID, NNTPReply.HEAD_FOLLOWS);

        if (reply.getCode() == NNTPReply.HEAD_FOLLOWS) {
            try {
                // wrap a stream around the reply data and read as headers.
                updateHeaders(new StringListInputStream(reply.getData()));
            } catch (IOException e) {
                throw new MessagingException("Error retrieving article headers from server", e);
            }
        } else {
            throw new MessagingException("Error retrieving article headers from server: " + reply);
        }
    }

    /**
     * Update the message headers from an input stream.
     * 
     * @param in
     *            The InputStream source for the header information.
     * 
     * @exception MessagingException
     */
    public void updateHeaders(InputStream in) throws MessagingException {
        // wrap a stream around the reply data and read as headers.
        headers = new InternetHeaders(in);
        headersLoaded = true;
    }

    /**
     * Load just the message content from the NNTP server.
     * 
     * @exception MessagingException
     */
    public void loadContent() throws MessagingException {
        if (contentLoaded) {
            return;
        }

        NNTPReply reply = connection.sendCommand("BODY " + messageID, NNTPReply.BODY_FOLLOWS);

        if (reply.getCode() == NNTPReply.BODY_FOLLOWS) {
            try {
                InputStream in = new StringListInputStream(reply.getData());
                updateContent(in);
            } catch (IOException e) {
                throw new MessagingException("Error retrieving article body from server", e);
            }
        } else {
            throw new MessagingException("Error retrieving article body from server: " + reply);
        }
    }

    /**
     * Load the entire article from the NNTP server. This updates both the
     * headers and the content.
     * 
     * @exception MessagingException
     */
    public void loadArticle() throws MessagingException {
        // if the headers are already loaded, retrieve the content portion.
        if (headersLoaded) {
            loadContent();
            return;
        }

        // we need to retrieve everything.
        NNTPReply reply = connection.sendCommand("ARTICLE " + messageID, NNTPReply.ARTICLE_FOLLOWS);

        if (reply.getCode() == NNTPReply.ARTICLE_FOLLOWS) {
            try {
                InputStream in = new StringListInputStream(reply.getData());
                // update both the headers and the content.
                updateHeaders(in);
                updateContent(in);
            } catch (IOException e) {
                throw new MessagingException("Error retrieving article from server", e);
            }
        } else {
            throw new MessagingException("Error retrieving article from server: " + reply);
        }
    }

    /**
     * Update the article content from an input stream.
     * 
     * @param in
     *            The content data source.
     * 
     * @exception MessagingException
     */
    public void updateContent(InputStream in) throws MessagingException {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            byte[] buffer = new byte[4096];

            // copy the content data from the stream into a byte buffer for the
            // content.
            while (true) {
                int read = in.read(buffer);
                if (read == -1) {
                    break;
                }
                out.write(buffer, 0, read);
            }

            content = out.toByteArray();
            contentLoaded = true;
        } catch (IOException e) {
            throw new MessagingException("Error retrieving message body from server", e);
        }
    }

    /**
     * Get the server assigned messageid for the article.
     * 
     * @return The server assigned message id.
     */
    public String getMessageId() {
        return messageID;
    }

    /**
     * Override of setFlags(). We need to ensure that if the SEEN flag is set or
     * cleared, that the newsrc file correctly reflects the current state.
     * 
     * @param flag
     *            The flag being set.
     * @param newvalue
     *            The new flag value.
     * 
     * @exception MessagingException
     */
    public void setFlags(Flags flag, boolean newvalue) throws MessagingException {
        // if this is the SEEN flag, make sure we shadow this in the newsrc
        // file.
        if (flag.contains(Flags.Flag.SEEN)) {
            ((NNTPFolder) folder).setSeen(msgnum, newvalue);
        }
        // have the superclass do the real flag setting.
        super.setFlags(flag, newvalue);
    }
}
