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

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;
import javax.mail.internet.ContentDisposition;
import javax.mail.internet.ContentType;

import org.apache.geronimo.javamail.util.ResponseFormatException;


public class IMAPBodyStructure extends IMAPFetchDataItem {

    // the MIME type information
    public ContentType mimeType = new ContentType();
    // the content disposition info
    public ContentDisposition disposition = null;
    // the message ID
    public String contentID;
    public String contentDescription;
    public String transferEncoding;
    // size of the message 
    public int bodySize;
    // number of lines, which only applies to text types.
    public int lines = -1;

    // "parts is parts".  If this is a multipart message, we have a body structure item for each subpart.
    public IMAPBodyStructure[] parts;
    // optional dispostiion parameters
    public Map dispositionParameters;
    // language parameters
    public List languages;
    // the MD5 hash
    public String md5Hash;

    // references to nested message information.
    public IMAPEnvelope nestedEnvelope;
    public IMAPBodyStructure nestedBody;


    public IMAPBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
        super(BODYSTRUCTURE);
        parseBodyStructure(source);
    }


    protected void parseBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
        // the body structure needs to start with a left paren
        source.checkLeftParen();

        // if we start with a parentized item, we have a multipart content type.  We need to
        // recurse on each of those as appropriate
        if (source.peek().getType() == '(') {
            parseMultipartBodyStructure(source);
        }
        else {
            parseSinglepartBodyStructure(source);
        }
    }


    protected void parseMultipartBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
        mimeType.setPrimaryType("multipart");
        ArrayList partList = new ArrayList();

        do {
            // parse the subpiece (which might also be a multipart).
            IMAPBodyStructure part = new IMAPBodyStructure(source);
            partList.add(part);
            // we keep doing this as long as we seen parenthized items.
        } while (source.peek().getType() == '(');
        
        parts = (IMAPBodyStructure[])partList.toArray(new IMAPBodyStructure[partList.size()]); 

        // get the subtype (required)
        mimeType.setSubType(source.readString());

        // if the next token is the list terminator, we're done.  Otherwise, we need to read extension
        // data.
        if (source.checkListEnd()) {
            return;
        }
        // read the content parameter information and copy into the ContentType.
        mimeType.setParameterList(source.readParameterList());

        // more optional stuff
        if (source.checkListEnd()) {
            return;
        }

        // go parse the extensions that are common to both single- and multi-part messages.
        parseMessageExtensions(source);
    }


    protected void parseSinglepartBodyStructure(IMAPResponseTokenizer source) throws MessagingException {
        // get the primary and secondary types.
        mimeType.setPrimaryType(source.readString());
        mimeType.setSubType(source.readString());

        // read the parameters associated with the content type.
        mimeType.setParameterList(source.readParameterList());

        // now a bunch of string value parameters
        contentID = source.readStringOrNil();
        contentDescription = source.readStringOrNil();
        transferEncoding = source.readStringOrNil();
        bodySize = source.readInteger();

        // is this an embedded message type?  Embedded messages include envelope and body structure
        // information for the embedded message next.
        if (mimeType.match("message/rfc822")) {
            // parse the nested information
            nestedEnvelope = new IMAPEnvelope(source);
            nestedBody = new IMAPBodyStructure(source);
            lines = source.readInteger();
        }
        // text types include a line count
        else if (mimeType.match("text/*")) {
            lines = source.readInteger();
        }

        // now the optional extension data.  All of these are optional, but must be in the specified order.
        if (source.checkListEnd()) {
            return;
        }

        md5Hash = source.readString();

        // go parse the extensions that are common to both single- and multi-part messages.
        parseMessageExtensions(source);
    }

    /**
     * Parse common message extension information shared between
     * single part and multi part messages.
     *
     * @param source The source tokenizer..
     */
    protected void parseMessageExtensions(IMAPResponseTokenizer source) throws MessagingException {

        // now the optional extension data.  All of these are optional, but must be in the specified order.
        if (source.checkListEnd()) {
            return;
        }

        disposition = new ContentDisposition();
        // now the dispostion.  This is a string, followed by a parameter list.
        if (source.peek(true).getType() == '(') {
            source.checkLeftParen();
            disposition.setDisposition(source.readString());
            disposition.setParameterList(source.readParameterList());
            source.checkRightParen();
        } else if (source.peek(true) == IMAPResponseTokenizer.NIL) {
            source.next();
        } else {
            throw new ResponseFormatException("Expecting NIL or '(' in response");
        }

        // once more
        if (source.checkListEnd()) {
            return;
        }
        // read the language info.
        languages = source.readStringList();
        // next is the body location information.  The Javamail APIs don't really expose that, so
        // we'll just skip over that.

        // once more
        if (source.checkListEnd()) {
            return;
        }
        // read the location info.
        source.readStringList();

        // we don't recognize any other forms of extension, so just skip over these.
        while (source.notListEnd()) {
            source.skipExtensionItem();
        }

        // step over the closing paren
        source.next();
    }


    /**
     * Tests if a body structure is for a multipart body.
     *
     * @return true if this is a multipart body part, false for a single part.
     */
    public boolean isMultipart() {
        return parts != null;
    }
    
    
    /**
     * Test if this body structure represents an attached message.  If it's a
     * message, this will be a single part of MIME type message/rfc822. 
     * 
     * @return True if this is a nested message type, false for either a multipart or 
     *         a single part of another type.
     */
    public boolean isAttachedMessage() {
        return !isMultipart() && mimeType.match("message/rfc822"); 
    }
}

