/*
 * Copyright 2012 s_wolff.
 *
 * Licensed 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.aegee.runanddine.advertisement;

import java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.MessagingException;

import org.aegee.runanddine.archive.ArchiveEntry;
import org.aegee.runanddine.mail.Mail;
import org.aegee.runanddine.mail.MailService;
import org.aegee.runanddine.mail.MailServiceListener;
import org.aegee.runanddine.mail.RHRKMailFactory;
import org.aegee.runanddine.status.RunAndDineStatus;
import org.aegee.runanddine.util.data.ModelNotExistingException;

/**
 * Class for perserving a mail between page reloads. Furthermore it serves to
 * save the information of the
 * <code>AdvertisementMailEditor</code>, e.g. the recipiants.
 *
 * @author s_wolff
 */
class TemporaryMail implements Serializable {

    /**
     * Mail subject
     */
    private String subject;
    /**
     * Mail content
     */
    private String content;
    /**
     * List of recipients
     */
    private Collection<MailingList> recipients;
    /**
     * MailRenderer
     */
    private AdvertisementMailRenderer renderer;
    /**
     * ID of corresponding RunAndDine
     */
    private int runAndDineId;
    /**
     * Send to RHRK flag
     */
    private boolean toRhrk = true;
    /**
     * Send to archive flag
     */
    private boolean toArchive = true;

    /**
     * Create TemporaryMail for RunAndDine with default template
     *
     * @param runAndDineId RunAndDine to be promoted
     */
    TemporaryMail(int runAndDineId) {
        this(runAndDineId, AdvertisementMailTemplate.getTemplate());
    }

    /**
     * Create TemporaryMail for RunAndDine with given template
     *
     * @param runAndDineId RunAndDine to be promoted
     * @param template Template to be used
     */
    TemporaryMail(int runAndDineId, AdvertisementMailTemplate template) {
        this.runAndDineId = runAndDineId;
        this.subject = template.getSubject();
        this.content = template.getContent();
        this.recipients = new LinkedList<MailingList>();
        try {
            this.renderer = getRenderer(this.runAndDineId);
        } catch (ModelNotExistingException ex) {
            Logger.getLogger(TemporaryMail.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Get ID of RunAndDine to be promoted
     *
     * @return ID of RunAndDine to be promoted
     */
    public int getRunAndDineId() {
        return runAndDineId;
    }

    /**
     * Set ID of RunAndDine to be promoted
     *
     * @param runAndDineId ID of RunAndDine to be promoted
     */
    public void setRunAndDineId(int runAndDineId) {
        this.runAndDineId = runAndDineId;
    }

    /**
     * Get MailRenderer
     *
     * @param id ID of RunAndDine to be promoted
     * @return MailRenderer for AdvertisementMail
     * @throws ModelNotExistingException
     */
    private static AdvertisementMailRenderer getRenderer(int id) throws ModelNotExistingException {
        return AdvertisementMailRenderer.create(id);
    }

    /**
     * Get mail content
     *
     * @return Mail content
     */
    String getContent() {
        return this.content;
    }

    /**
     * Get rendered mail content
     *
     * @return Rendered content
     */
    String getRenderedContent() {
        return this.renderer.render(this.content);
    }

    /**
     * Get mail subject
     *
     * @return Mail subject
     */
    String getSubject() {
        return this.subject;
    }

    /**
     * Get rendered mail subject
     *
     * @return Rendered subject
     */
    String getRenderedSubject() {
        return this.renderer.render(this.subject);
    }

    /**
     * Set mail content
     *
     * @param content
     */
    void setContent(String content) {
        this.content = content.replace("{{ ", "{{").replace(" }}", "}}");
    }

    /**
     * Set mail subject
     *
     * @param subject Mail subject
     */
    void setSubject(String subject) {
        this.subject = subject.replace("{{ ", "{{").replace(" }}", "}}");
    }

    /**
     * Set "Send to RHRK"-flag
     *
     * @param toRhrk "Send to RHRK"-flag
     */
    void setToRhrk(boolean toRhrk) {
        this.toRhrk = toRhrk;
    }

    /**
     * Set "Send to archive"-flag
     *
     * @param toArchive "Send to archive"-flag
     */
    void setToArchive(boolean toArchive) {
        this.toArchive = toArchive;
    }

    /**
     * Get "Send to archive"-flag
     *
     * @return "Send to archive"-flag
     */
    boolean isToArchive() {
        return toArchive;
    }

    /**
     * Get "Send to RHRK"-flag
     *
     * @return "Send to RHRK"-flag
     */
    boolean isToRhrk() {
        return toRhrk;
    }

    /**
     * Get list of recipients
     *
     * @return List of recipients
     */
    Collection<MailingList> getRecipients() {
        return this.recipients;
    }

    /**
     * Add or remove recipient from TemporaryMail
     *
     * @param obj Recipient to be added/removed
     * @param add Set to true if recipient should be added
     */
    void editRecipiants(MailingList obj, boolean add) {
        if (add) {
            this.addRecipiant(obj);
        } else {
            this.removeRecipiant(obj);
        }
    }

    /**
     * Add recipient
     *
     * @param obj Recipient to be added
     */
    void addRecipiant(MailingList obj) {
        this.recipients.add(obj);
    }

    /**
     * Remove recipient
     *
     * @param obj Recipient to be removed
     */
    void removeRecipiant(MailingList obj) {
        this.recipients.remove(obj);
    }

    /**
     * Check if mail already has given recipient
     *
     * @param obj Recipient to be checked
     * @return Mail has recipient
     */
    boolean containsRecipiant(MailingList obj) {
        return this.recipients.contains(obj);
    }

    /**
     * Get MailRenderer
     *
     * @return MailRenderer
     */
    AdvertisementMailRenderer getRenderer() {
        return this.renderer;
    }

    /**
     * Send mail
     */
    void send() {
        String renderedSubject = this.getRenderedSubject();
        String renderedContent = this.getRenderedContent();

        Collection<Mail> mails = new LinkedList<Mail>();
        for (MailingList ml : this.recipients) {
            mails.add(new Mail(renderedSubject, ml.getAddress(), "", renderedContent));
        }

        if (this.toArchive) {
            Collection<ArchiveEntry> archive = ArchiveEntry.OBJECTS.getAll();
            for (ArchiveEntry e : archive) {
                if (e.isRadMailFlag() || e.isAegeeMailFlag()) {
                    mails.add(new Mail(renderedSubject, e.getEmail(), "", renderedContent));
                }
            }
        }

        if (this.toRhrk) {
            mails.add(RHRKMailFactory.make(renderedSubject, renderedContent));
        }
        MailService.getInstance().sendMail(mails, new MailServiceListener() {

            public void mailsSend() {
                RunAndDineStatus.setStatusInformation(runAndDineId, AdvertisementMailEditor.class, "Mails sent");
            }

            public void failure(MessagingException ex) {
                // will never be called
            }
        });
    }
}
