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

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.apache.james.mime4j.dom.Body;
import org.apache.james.mime4j.dom.Header;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.dom.address.Address;
import org.apache.james.mime4j.dom.address.AddressList;
import org.apache.james.mime4j.dom.address.Mailbox;
import org.apache.james.mime4j.dom.address.MailboxList;
import org.apache.james.mime4j.dom.field.AddressListField;
import org.apache.james.mime4j.dom.field.DateTimeField;
import org.apache.james.mime4j.dom.field.FieldName;
import org.apache.james.mime4j.dom.field.MailboxField;
import org.apache.james.mime4j.dom.field.MailboxListField;
import org.apache.james.mime4j.dom.field.ParseException;
import org.apache.james.mime4j.dom.field.UnstructuredField;
import org.apache.james.mime4j.field.Fields;
import org.apache.james.mime4j.field.address.AddressBuilder;
import org.apache.james.mime4j.stream.Field;
import org.apache.james.mime4j.stream.NameValuePair;

/**
 * {@link org.apache.james.mime4j.dom.Message} builder.
 */
public class MessageBuilder extends AbstractEntityBuilder {

    public static MessageBuilder create() {
        return new MessageBuilder();
    }

    @Override
    public MessageBuilder setField(Field field) {
        super.setField(field);
        return this;
    }

    @Override
    public AbstractEntityBuilder addField(Field field) {
        super.addField(field);
        return this;
    }

    @Override
    public AbstractEntityBuilder removeFields(String name) {
        super.removeFields(name);
        return this;
    }

    @Override
    public MessageBuilder setContentTransferEncoding(String contentTransferEncoding) {
        super.setContentTransferEncoding(contentTransferEncoding);
        return this;
    }

    @Override
    public MessageBuilder setContentType(String mimeType, NameValuePair... parameters) {
        super.setContentType(mimeType, parameters);
        return this;
    }

    @Override
    public MessageBuilder setContentDisposition(String dispositionType) {
        super.setContentDisposition(dispositionType);
        return this;
    }

    @Override
    public MessageBuilder setContentDisposition(String dispositionType, String filename) {
        super.setContentDisposition(dispositionType, filename);
        return this;
    }

    @Override
    public MessageBuilder setContentDisposition(String dispositionType, String filename, long size) {
        super.setContentDisposition(dispositionType, filename, size);
        return this;
    }

    @Override
    public MessageBuilder setContentDisposition(String dispositionType, String filename, long size,
                                                Date creationDate, Date modificationDate, Date readDate) {
        super.setContentDisposition(dispositionType, filename, size, creationDate, modificationDate, readDate);
        return this;
    }

    @Override
    public MessageBuilder setBody(Body body) {
        super.setBody(body);
        return this;
    }

    @Override
    public MessageBuilder use(final BodyFactory bodyFactory) {
        super.use(bodyFactory);
        return this;
    }

    @Override
    public MessageBuilder setBody(String text, Charset charset) throws IOException {
        super.setBody(text, charset);
        return this;
    }

    @Override
    public MessageBuilder setBody(String text, String subtype, Charset charset) throws IOException {
        super.setBody(text, subtype, charset);
        return this;
    }

    /**
     * Returns the value of the <i>Message-ID</i> header field of this message
     * or <code>null</code> if it is not present.
     *
     * @return the identifier of this message.
     */
    public String getMessageId() {
        Field field = obtainField(FieldName.MESSAGE_ID);
        return field != null ? field.getBody() : null;
    }

    /**
     * Generates and sets message ID for this message.
     *
     * @param hostname
     *            host name to be included in the identifier or
     *            <code>null</code> if no host name should be included.
     */
    public MessageBuilder generateMessageId(String hostname) {
        if (hostname == null) {
            removeFields(FieldName.MESSAGE_ID);
        } else {
            setField(Fields.generateMessageId(hostname));
        }
        return this;
    }

    /**
     * Sets message ID for this message.
     *
     * @param messageId
     *            the message ID.
     */
    public MessageBuilder setMessageId(String messageId) {
        if (messageId == null) {
            removeFields(FieldName.MESSAGE_ID);
        } else {
            setField(Fields.messageId(messageId));
        }
        return this;
    }

    /**
     * Returns the (decoded) value of the <i>Subject</i> header field of this
     * message or <code>null</code> if it is not present.
     *
     * @return the subject of this message.
     */
    public String getSubject() {
        UnstructuredField field = obtainField(FieldName.SUBJECT);
        return field != null ? field.getValue() : null;
    }

    /**
     * Sets <i>Subject</i> header field for this message. The specified
     * string may contain non-ASCII characters, in which case it gets encoded as
     * an 'encoded-word' automatically.
     *
     * @param subject
     *            subject to set or <code>null</code> to remove the subject
     *            header field.
     */
    public MessageBuilder setSubject(String subject) {
        if (subject == null) {
            removeFields(FieldName.SUBJECT);
        } else {
            setField(Fields.subject(subject));
        }
        return this;
    }

    /**
     * Returns the value of the <i>Date</i> header field of this message as
     * <code>Date</code> object or <code>null</code> if it is not present.
     *
     * @return the date of this message.
     */
    public Date getDate() {
        DateTimeField field = obtainField(FieldName.DATE);
        return field != null ? field.getDate() : null;
    }

    /**
     * Sets <i>Date</i> header field for this message. This method uses the
     * default <code>TimeZone</code> of this host to encode the specified
     * <code>Date</code> object into a string.
     *
     * @param date
     *            date to set or <code>null</code> to remove the date header
     *            field.
     */
    public MessageBuilder setDate(Date date) {
        return setDate(date, null);
    }

    /**
     * Sets <i>Date</i> header field for this message. The specified
     * <code>TimeZone</code> is used to encode the specified <code>Date</code>
     * object into a string.
     *
     * @param date
     *            date to set or <code>null</code> to remove the date header
     *            field.
     * @param zone
     *            a time zone.
     */
    public MessageBuilder setDate(Date date, TimeZone zone) {
        if (date == null) {
            removeFields(FieldName.DATE);
        } else {
            setField(Fields.date(FieldName.DATE, date, zone));
        }
        return this;
    }

    /**
     * Returns the value of the <i>Sender</i> header field of this message as
     * <code>Mailbox</code> object or <code>null</code> if it is not
     * present.
     *
     * @return the sender of this message.
     */
    public Mailbox getSender() {
        return getMailbox(FieldName.SENDER);
    }

    /**
     * Sets <i>Sender</i> header field of this message to the specified
     * mailbox address.
     *
     * @param sender
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setSender(Mailbox sender) {
        return setMailbox(FieldName.SENDER, sender);
    }

    /**
     * Sets <i>Sender</i> header field of this message to the specified
     * mailbox address.
     *
     * @param sender
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setSender(String sender) throws ParseException {
        return setMailbox(FieldName.SENDER, sender);
    }

    /**
     * Returns the value of the <i>From</i> header field of this message as
     * <code>MailboxList</code> object or <code>null</code> if it is not
     * present.
     *
     * @return value of the from field of this message.
     */
    public MailboxList getFrom() {
        return getMailboxList(FieldName.FROM);
    }

    /**
     * Sets <i>From</i> header field of this message to the specified
     * mailbox address.
     *
     * @param from
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setFrom(Mailbox from) {
        return setMailboxList(FieldName.FROM, from);
    }

    /**
     * Sets <i>From</i> header field of this message to the specified
     * mailbox address.
     *
     * @param from
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setFrom(String from) throws ParseException {
        return setMailboxList(FieldName.FROM, from);
    }

    /**
     * Sets <i>From</i> header field of this message to the specified
     * mailbox addresses.
     *
     * @param from
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setFrom(Mailbox... from) {
        return setMailboxList(FieldName.FROM, from);
    }

    /**
     * Sets <i>From</i> header field of this message to the specified
     * mailbox addresses.
     *
     * @param from
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setFrom(String... from) throws ParseException {
        return setMailboxList(FieldName.FROM, from);
    }

    /**
     * Sets <i>From</i> header field of this message to the specified
     * mailbox addresses.
     *
     * @param from
     *            addresses to set or <code>null</code> or an empty collection
     *            to remove the header field.
     */
    public MessageBuilder setFrom(Collection<Mailbox> from) {
        return setMailboxList(FieldName.FROM, from);
    }

    /**
     * Returns the value of the <i>To</i> header field of this message as
     * <code>AddressList</code> object or <code>null</code> if it is not
     * present.
     *
     * @return value of the to field of this message.
     */
    public AddressList getTo() {
        return getAddressList(FieldName.TO);
    }

    /**
     * Sets <i>To</i> header field of this message to the specified
     * address.
     *
     * @param to
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setTo(Address to) {
        return setAddressList(FieldName.TO, to);
    }

    /**
     * Sets <i>To</i> header field of this message to the specified
     * address.
     *
     * @param to
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setTo(String to) throws ParseException {
        return setAddressList(FieldName.TO, to);
    }

    /**
     * Sets <i>To</i> header field of this message to the specified
     * addresses.
     *
     * @param to
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setTo(Address... to) {
        return setAddressList(FieldName.TO, to);
    }

    /**
     * Sets <i>To</i> header field of this message to the specified
     * addresses.
     *
     * @param to
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setTo(String... to) throws ParseException {
        return setAddressList(FieldName.TO, to);
    }

    /**
     * Sets <i>To</i> header field of this message to the specified
     * addresses.
     *
     * @param to
     *            addresses to set or <code>null</code> or an empty collection
     *            to remove the header field.
     */
    public MessageBuilder setTo(Collection<? extends Address> to) {
        return setAddressList(FieldName.TO, to);
    }

    /**
     * Returns the value of the <i>Cc</i> header field of this message as
     * <code>AddressList</code> object or <code>null</code> if it is not
     * present.
     *
     * @return value of the cc field of this message.
     */
    public AddressList getCc() {
        return getAddressList(FieldName.CC);
    }

    /**
     * Sets <i>Cc</i> header field of this message to the specified
     * address.
     *
     * @param cc
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setCc(Address cc) {
        return setAddressList(FieldName.CC, cc);
    }

    /**
     * Sets <i>Cc</i> header field of this message to the specified
     * addresses.
     *
     * @param cc
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setCc(Address... cc) {
        return setAddressList(FieldName.CC, cc);
    }

    /**
     * Sets <i>Cc</i> header field of this message to the specified
     * addresses.
     *
     * @param cc
     *            addresses to set or <code>null</code> or an empty collection
     *            to remove the header field.
     */
    public MessageBuilder setCc(Collection<? extends Address> cc) {
        return setAddressList(FieldName.CC, cc);
    }

    /**
     * Returns the value of the <i>Bcc</i> header field of this message as
     * <code>AddressList</code> object or <code>null</code> if it is not
     * present.
     *
     * @return value of the bcc field of this message.
     */
    public AddressList getBcc() {
        return getAddressList(FieldName.BCC);
    }

    /**
     * Sets <i>Bcc</i> header field of this message to the specified
     * address.
     *
     * @param bcc
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setBcc(Address bcc) {
        return setAddressList(FieldName.BCC, bcc);
    }

    /**
     * Sets <i>Bcc</i> header field of this message to the specified
     * addresses.
     *
     * @param bcc
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setBcc(Address... bcc) {
        return setAddressList(FieldName.BCC, bcc);
    }

    /**
     * Sets <i>Bcc</i> header field of this message to the specified
     * addresses.
     *
     * @param bcc
     *            addresses to set or <code>null</code> or an empty collection
     *            to remove the header field.
     */
    public MessageBuilder setBcc(Collection<? extends Address> bcc) {
        return setAddressList(FieldName.BCC, bcc);
    }

    /**
     * Returns the value of the <i>Reply-To</i> header field of this message as
     * <code>AddressList</code> object or <code>null</code> if it is not
     * present.
     *
     * @return value of the reply to field of this message.
     */
    public AddressList getReplyTo() {
        return getAddressList(FieldName.REPLY_TO);
    }

    /**
     * Sets <i>Reply-To</i> header field of this message to the specified
     * address.
     *
     * @param replyTo
     *            address to set or <code>null</code> to remove the header
     *            field.
     */
    public MessageBuilder setReplyTo(Address replyTo) {
        return setAddressList(FieldName.REPLY_TO, replyTo);
    }

    /**
     * Sets <i>Reply-To</i> header field of this message to the specified
     * addresses.
     *
     * @param replyTo
     *            addresses to set or <code>null</code> or no arguments to
     *            remove the header field.
     */
    public MessageBuilder setReplyTo(Address... replyTo) {
        return setAddressList(FieldName.REPLY_TO, replyTo);
    }

    /**
     * Sets <i>Reply-To</i> header field of this message to the specified
     * addresses.
     *
     * @param replyTo
     *            addresses to set or <code>null</code> or an empty collection
     *            to remove the header field.
     */
    public MessageBuilder setReplyTo(Collection<? extends Address> replyTo) {
        return setAddressList(FieldName.REPLY_TO, replyTo);
    }

    private Mailbox getMailbox(String fieldName) {
        MailboxField field = obtainField(fieldName);
        return field != null ? field.getMailbox() : null;
    }

    private MessageBuilder setMailbox(String fieldName, Mailbox mailbox) {
        if (mailbox == null) {
            removeFields(fieldName);
        } else {
            setField(Fields.mailbox(fieldName, mailbox));
        }
        return this;
    }

    private MessageBuilder setMailbox(String fieldName, String mailbox) throws ParseException {
        if (mailbox == null) {
            removeFields(fieldName);
        } else {
            setField(Fields.mailbox(fieldName, AddressBuilder.DEFAULT.parseMailbox(mailbox)));
        }
        return this;
    }

    private MailboxList getMailboxList(String fieldName) {
        MailboxListField field = obtainField(fieldName);
        return field != null ? field.getMailboxList() : null;
    }

    private MessageBuilder setMailboxList(String fieldName, Mailbox mailbox) {
        return setMailboxList(fieldName, mailbox == null ? null : Collections.singleton(mailbox));
    }

    private MessageBuilder setMailboxList(String fieldName, String mailbox) throws ParseException {
        return setMailboxList(fieldName, mailbox == null ? null : AddressBuilder.DEFAULT.parseMailbox(mailbox));
    }

    private MessageBuilder setMailboxList(String fieldName, Mailbox... mailboxes) {
        return setMailboxList(fieldName, mailboxes == null ? null : Arrays.asList(mailboxes));
    }

    private List<Mailbox> parseMailboxes(String... mailboxes) throws ParseException {
        if (mailboxes == null || mailboxes.length == 0) {
            return null;
        } else {
            List<Mailbox> list = new ArrayList<Mailbox>();
            for (String mailbox: mailboxes) {
                list.add(AddressBuilder.DEFAULT.parseMailbox(mailbox));
            }
            return list;
        }
    }

    private MessageBuilder setMailboxList(String fieldName, String... mailboxes) throws ParseException {
        return setMailboxList(fieldName, parseMailboxes(mailboxes));
    }

    private MessageBuilder setMailboxList(String fieldName, Collection<Mailbox> mailboxes) {
        if (mailboxes == null || mailboxes.isEmpty()) {
            removeFields(fieldName);
        } else {
            setField(Fields.mailboxList(fieldName, mailboxes));
        }
        return this;
    }

    private AddressList getAddressList(String fieldName) {
        AddressListField field = obtainField(fieldName);
        return field != null? field.getAddressList() : null;
    }

    private MessageBuilder setAddressList(String fieldName, Address address) {
        return setAddressList(fieldName, address == null ? null : Collections.singleton(address));
    }

    private MessageBuilder setAddressList(String fieldName, String address) throws ParseException {
        return setAddressList(fieldName, address == null ? null :AddressBuilder.DEFAULT.parseMailbox(address));
    }

    private MessageBuilder setAddressList(String fieldName, Address... addresses) {
        return setAddressList(fieldName, addresses == null ? null : Arrays.asList(addresses));
    }

    private List<Address> parseAddresses(String... addresses) throws ParseException {
        if (addresses == null || addresses.length == 0) {
            return null;
        } else {
            List<Address> list = new ArrayList<Address>();
            for (String address: addresses) {
                list.add(AddressBuilder.DEFAULT.parseAddress(address));
            }
            return list;
        }
    }

    private MessageBuilder setAddressList(String fieldName, String... addresses) throws ParseException {
        return setAddressList(fieldName, parseAddresses(addresses));
    }

    private MessageBuilder setAddressList(String fieldName, Collection<? extends Address> addresses) {
        if (addresses == null || addresses.isEmpty()) {
            removeFields(fieldName);
        } else {
            setField(Fields.addressList(fieldName, addresses));
        }
        return this;
    }

    public Message build() {
        MessageImpl message = new MessageImpl();
        Header header = message.getHeader();
        if (!containsField(FieldName.MIME_VERSION)) {
            header.setField(Fields.version("1.0"));
        }
        for (Field field : getFields()) {
            header.addField(field);
        }
        if (!containsField(FieldName.DATE)) {
            header.setField(Fields.date(new Date()));
        }

        message.setBody(getBody());

        return message;
    }

}
