/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.mail;

import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.naming.NamingException;
import javax.naming.Reference;

import org.jfox.framework.extra.ActiveComponent;
import org.jfox.framework.extra.Managable;
import org.jfox.framework.extra.ManagementInfo;
import org.jfox.jndi.InitialContextHelper;
import org.jfox.system.AbstractService;

/**
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class MailService extends AbstractService implements Managable, ActiveComponent {
    private String user;
    private String password;
    private String m_jndiName = "mail";

    private final static String mailStoreProtocolKey = "mail.store.protocol";
    private String mailStoreProtocol = "pop3";

    private final static String mailTransportProtocolKey = "mail.transport.protocol";
    private String mailTransportProtocol = "smtp";

    private final static String mailPop3HostKey = "mail.pop3.host";
    private String mailPop3Host = "pop3.foxsource.org";

    private final static String mailSmtpHostKey = "mail.smtp.host";
    private String mailSmtpHost = "smtp.foxsource.org";

    private final static String mailFromKey = "mail.from";
    private String mailFrom = "young_yy@hotmail.com";

    private final static String mailSmtpAuthKey = "mail.smtp.auth";
    private boolean mailSmtpAuth = false;


    private Session session = null;

    public void setUser(String user) {
        this.user = user;
    }

    public String getUser() {
        return user;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

    public String getMailStoreProtocol() {
        return mailStoreProtocol;
    }

    public void setMailStoreProtocol(String mailStoreProtocol) {
        this.mailStoreProtocol = mailStoreProtocol;
    }

    public String getMailTransportProtocol() {
        return mailTransportProtocol;
    }

    public void setMailTransportProtocol(String mailTransportProtocol) {
        this.mailTransportProtocol = mailTransportProtocol;
    }

    public String getMailPop3Host() {
        return mailPop3Host;
    }

    public void setMailPop3Host(String mailPop3Host) {
        this.mailPop3Host = mailPop3Host;
    }

    public String getMailSmtpHost() {
        return mailSmtpHost;
    }

    public void setMailSmtpHost(String mailSmtpHost) {
        this.mailSmtpHost = mailSmtpHost;
    }

    public String getMailFrom() {
        return mailFrom;
    }

    public void setMailFrom(String mailFrom) {
        this.mailFrom = mailFrom;
    }

    public void setJNDIName(String name) {
        if(this.isInitialized()) {
            logger.warn("Mail Service has started, can't change JNDI name.");
        }
        else {
            m_jndiName = name;
        }
    }

    public String getJNDIName() {
        return m_jndiName;
    }

    public boolean isMailSmtpAuth() {
        return mailSmtpAuth;
    }

    public void setMailSmtpAuth(boolean mailSmtpAuth) {
        this.mailSmtpAuth = mailSmtpAuth;
    }

    protected void doInit() throws Exception {
        final PasswordAuthentication pa = new PasswordAuthentication(getUser(), getPassword());
        Authenticator auth = new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return pa;
            }
        };
        Properties prop = new Properties();
        prop.setProperty(mailStoreProtocolKey, getMailStoreProtocol());
        prop.setProperty(mailTransportProtocolKey, getMailTransportProtocol());
        prop.setProperty(mailPop3HostKey, getMailPop3Host());
        prop.setProperty(mailSmtpHostKey, getMailSmtpHost());
        prop.setProperty(mailFromKey, getMailFrom());

        if(isMailSmtpAuth()) {
            prop.setProperty(mailSmtpAuthKey, "true");
        }


        // Finally create auth mail session
        session = Session.getInstance(prop, auth);

    }

    protected void doDestroy() throws Exception {
        session = null;
    }

    public void run() {
        // ignore, not need start new thread
    }

    protected void doStart() throws Exception {
        bind(session);
    }

    protected void doStop() {
        MailSessionObjectFactory.removeMailSession(getJNDIName());
        // Unbind from JNDI
        try {
            unbind();
        }
        catch(NamingException x) {
            logger.error("unbind failure", x);
        }
    }

    private void bind(Session session) throws NamingException {
        String bindName = getJNDIName();
        Reference ref = new Reference(Session.class.getName(), MailSessionObjectFactory.class.getName(), null);
        InitialContextHelper.getInitialContext().bind(bindName, ref);

        MailSessionObjectFactory.addMailSession(bindName, session);
        logger.info("Mail Service bound to " + bindName);
    }

    private void unbind() throws NamingException {
        String bindName = getJNDIName();
        InitialContextHelper.getInitialContext().unbind(bindName);
        logger.info("Mail service '" + getJNDIName() + "' removed from JNDI");
    }

    public ManagementInfo getManagementInfo() {
        return ManagementInfo.exposePublic(MailService.class);
    }

    public static void main(String[] args) {

    }
}
