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

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

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

import org.apache.geronimo.javamail.store.pop3.POP3CommandFactory;
import org.apache.geronimo.javamail.store.pop3.POP3Connection;
import org.apache.geronimo.javamail.store.pop3.POP3Folder;
import org.apache.geronimo.javamail.store.pop3.POP3Response;
import org.apache.geronimo.javamail.store.pop3.response.POP3ListResponse;
import org.apache.geronimo.javamail.store.pop3.response.POP3ResponseFactory;

/**
 * POP3 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$ $Date$
 */
public class POP3Message extends MimeMessage {

    private POP3Connection pop3Con;

    private int msgSize = -1;

    private int headerSize = -1;

    // We can't use header bcos it's already initialize to
    // to an empty InternetHeader
    private InputStream rawHeaders;

    // used to force loading of headers again
    private boolean loadHeaders = true;

    // to get accessed to the debug setting and log
    private Session session;

    protected POP3Message(Folder folder, int msgnum, Session session, POP3Connection pop3Con) {
        super(folder, msgnum);
        this.pop3Con = pop3Con;
        this.session = session;
    }

    /**
     * @see javax.mail.internet.MimeMessage#getContentStream()
     */
    protected InputStream getContentStream() throws MessagingException {
        POP3Response msgResponse = null;
        try {
            msgResponse = pop3Con.sendCommand(POP3CommandFactory.getCOMMAND_RETR(msgnum));
        } catch (Exception e) {
            e.printStackTrace();
        }
        loadHeaders = true;
        loadHeaders(msgResponse.getData());
        loadContent(msgResponse.getData());

        return contentStream;
    }

    public void setFlags(Flags newFlags, boolean set) throws MessagingException {
        Flags oldFlags = (Flags) flags.clone();
        super.setFlags(newFlags, set);

        if (!flags.equals(oldFlags)) {
            ((POP3Folder) folder).notifyMessageChangedListeners(MessageChangedEvent.FLAGS_CHANGED, this);
        }
    }

    protected void loadHeaders(InputStream in) throws MessagingException {
        if (loadHeaders || rawHeaders == null) {
            rawHeaders = in;
            headers = new InternetHeaders(rawHeaders);
            loadHeaders = false;
        }
    }

    protected void loadContent(InputStream stream) throws MessagingException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            int byteRead = stream.read();
            int lastByte = -1;
            for (; byteRead > 0;) {
                if (byteRead == ' ' && lastByte == '\n') {
                    break;
                }
                lastByte = byteRead;
                byteRead = stream.read();
            }

            for (; stream.available() > 0;) {
                out.write(stream.read());
            }

            contentStream = new ByteArrayInputStream(out.toByteArray());
            msgSize = contentStream.available();

        } catch (IOException e) {

            throw new MessagingException("Error loading content info", e);
        }
    }

    public int getSize() throws MessagingException {
        if (msgSize >= 0) {
            return msgSize;
        }
        try {

            if (msgSize < 0) {
                if (rawHeaders == null) {
                    loadHeaders();
                }
                POP3ListResponse res = (POP3ListResponse) POP3ResponseFactory.getListResponse(pop3Con
                        .sendCommand(POP3CommandFactory.getCOMMAND_LIST(msgnum)));
                msgSize = res.getSize() - headerSize;
            }
            return msgSize;
        } catch (MessagingException ex) {
            throw new MessagingException("error getting size", ex);
        }
    }

    /**
     * notice that we pass zero as the no of lines from the message,as it
     * doesn't serv any purpose to get only a certain number of lines.
     * 
     * However this maybe important if a mail client only shows 3 or 4 lines of
     * the message in the list and then when the user clicks they would load the
     * message on demand.
     * 
     */
    protected void loadHeaders() throws MessagingException {
        POP3Response msgResponse = null;
        try {

            msgResponse = pop3Con.sendCommand(POP3CommandFactory.getCOMMAND_TOP(msgnum, 0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        loadHeaders(msgResponse.getData());
    }

    /***************************************************************************
     * Following is a set of methods that deal with headers I have tried to use
     * the bare minimum
     * 
     * Used sun's POP3 impl & JavaMail API as a guide in decided which methods
     * are important.
     **************************************************************************/

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

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

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

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

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

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

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

    public Enumeration getNonMatchingHeaderLines(String[] names) throws MessagingException {
        if (headers == null)
            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("POP3 messages are read-only");
    }

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

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

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

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