package org.apache.maven.continuum.notification.mail;

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

import org.apache.continuum.model.project.ProjectScmRoot;
import org.apache.maven.continuum.Continuum;
import org.apache.maven.continuum.configuration.ConfigurationService;
import org.apache.maven.continuum.execution.ExecutorConfigurator;
import org.apache.maven.continuum.execution.ant.AntBuildExecutor;
import org.apache.maven.continuum.execution.maven.m1.MavenOneBuildExecutor;
import org.apache.maven.continuum.execution.maven.m2.MavenTwoBuildExecutor;
import org.apache.maven.continuum.installation.InstallationException;
import org.apache.maven.continuum.installation.InstallationService;
import org.apache.maven.continuum.model.project.BuildDefinition;
import org.apache.maven.continuum.model.project.BuildResult;
import org.apache.maven.continuum.model.project.Project;
import org.apache.maven.continuum.model.project.ProjectDeveloper;
import org.apache.maven.continuum.model.project.ProjectGroup;
import org.apache.maven.continuum.model.project.ProjectNotifier;
import org.apache.maven.continuum.model.scm.ChangeSet;
import org.apache.maven.continuum.model.scm.ScmResult;
import org.apache.maven.continuum.model.system.Installation;
import org.apache.maven.continuum.model.system.Profile;
import org.apache.maven.continuum.notification.AbstractContinuumNotifier;
import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
import org.apache.maven.continuum.notification.MessageContext;
import org.apache.maven.continuum.notification.NotificationException;
import org.apache.maven.continuum.project.ContinuumProjectState;
import org.apache.maven.continuum.reports.surefire.ReportTestResult;
import org.apache.maven.continuum.reports.surefire.ReportTestSuiteGenerator;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.velocity.VelocityComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.javamail.JavaMailSender;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
 * @version $Id$
 */
public class MailContinuumNotifier
    extends AbstractContinuumNotifier
    implements Initializable
{
    private static final Logger log = LoggerFactory.getLogger( MailContinuumNotifier.class );

    // ----------------------------------------------------------------------
    // Requirements
    // ----------------------------------------------------------------------

    /**
     * @plexus.requirement
     */
    private VelocityComponent velocity;

    /**
     * @plexus.requirement
     */
    private ConfigurationService configurationService;

    /**
     * @plexus.requirement
     */
    private Continuum continuum;

    /**
     * @plexus.requirement
     */
    private JavaMailSender javaMailSender;

    /**
     * @plexus.requirement
     */
    private ReportTestSuiteGenerator reportTestSuiteGenerator;

    // ----------------------------------------------------------------------
    // Configuration
    // ----------------------------------------------------------------------

    /**
     * @plexus.configuration
     */
    private String fromMailbox;

    /**
     * @plexus.configuration
     */
    private String fromName;

    /**
     * @plexus.configuration
     */
    private String toOverride;

    /**
     * @plexus.configuration
     */
    private String timestampFormat;

    /**
     * @plexus.configuration
     */
    private boolean includeBuildSummary = true;

    /**
     * @plexus.configuration
     */
    private boolean includeTestSummary = true;

    /**
     * @plexus.configuration
     */
    private boolean includeBuildOutput = false;

    /**
     * Customizable mail subject.  Use any combination of literal text, project or build attributes.
     * Examples:
     * "[continuum] BUILD ${state}: ${project.groupId} ${project.name}" results in "[continuum] BUILD SUCCESSFUL: foo.bar Hello World"
     * "[continuum] BUILD ${state}: ${project.name} ${project.scmTag}" results in "[continuum] BUILD SUCCESSFUL: Hello World Branch001"
     * "[continuum] BUILD ${state}: ${project.name} ${build.durationTime}" results in "[continuum] BUILD SUCCESSFUL: Hello World 2 sec"
     * "[continuum] BUILD ${state}: ${project.name}, Build Def - ${build.buildDefinition.description}" results in "[continuum] BUILD SUCCESSFUL: Hello World, Build Def - Nightly Test Build"
     *
     * @plexus.configuration
     */
    private String buildSubjectFormat = "[continuum] BUILD ${state}: ${project.groupId} ${project.name}";

    /**
     * Customizable mail subject
     *
     * @plexus.configuration
     */
    private String prepareBuildSubjectFormat =
        "[continuum] PREPARE BUILD ${state]: ${projectScmRoot.projectGroup.name}";

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private String buildHost;

    private FormatterTool formatterTool;

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private static final String FALLBACK_FROM_MAILBOX = "continuum@localhost";

    // ----------------------------------------------------------------------
    // Component Lifecycle
    // ----------------------------------------------------------------------

    public void initialize()
    {
        try
        {
            InetAddress address = InetAddress.getLocalHost();

            buildHost = StringUtils.clean( address.getHostName() );

            if ( buildHost == null )
            {
                buildHost = "localhost";
            }
        }
        catch ( UnknownHostException ex )
        {
            fromName = "Continuum";
        }

        // ----------------------------------------------------------------------
        // From mailbox
        // ----------------------------------------------------------------------

        if ( StringUtils.isEmpty( fromMailbox ) )
        {
            log.info( "The from mailbox is not configured, will use the nag email address from the project." );

            fromMailbox = null;
        }
        else
        {
            log.info( "Using '" + fromMailbox + "' as the from mailbox for all emails." );
        }

        if ( StringUtils.isEmpty( fromName ) )
        {
            fromName = "Continuum@" + buildHost;
        }

        log.info( "From name: " + fromName );

        log.info( "Build host name: " + buildHost );

        // ----------------------------------------------------------------------
        //
        // ----------------------------------------------------------------------

        formatterTool = new FormatterTool( timestampFormat );
    }

    // ----------------------------------------------------------------------
    // Notifier Implementation
    // ----------------------------------------------------------------------

    public String getType()
    {
        return "mail";
    }

    public void sendMessage( String messageId, MessageContext context )
        throws NotificationException
    {
        Project project = context.getProject();
        List<ProjectNotifier> notifiers = context.getNotifiers();
        BuildResult build = context.getBuildResult();

        if ( build != null )
        {
            log.error( "br state=" + build.getState() );
        }

        if ( project != null )
        {
            log.error( "project state=" + project.getState() );
        }

        BuildDefinition buildDefinition = context.getBuildDefinition();
        ProjectScmRoot projectScmRoot = context.getProjectScmRoot();

        boolean isPrepareBuildComplete = messageId.equals(
            ContinuumNotificationDispatcher.MESSAGE_ID_PREPARE_BUILD_COMPLETE );

        if ( projectScmRoot == null && isPrepareBuildComplete )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // If there wasn't any building done, don't notify
        // ----------------------------------------------------------------------

        if ( build == null && !isPrepareBuildComplete )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // Generate and send email
        // ----------------------------------------------------------------------

        if ( messageId.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_COMPLETE ) )
        {
            buildComplete( project, notifiers, build, messageId, context, buildDefinition );
        }
        else if ( isPrepareBuildComplete )
        {
            prepareBuildComplete( projectScmRoot, notifiers, messageId, context );
        }
    }

    private void buildComplete( Project project, List<ProjectNotifier> notifiers, BuildResult build, String messageId,
                                MessageContext context, BuildDefinition buildDefinition )
        throws NotificationException
    {
        BuildResult previousBuild = getPreviousBuild( project, buildDefinition, build );

        List<ProjectNotifier> notifiersList = new ArrayList<ProjectNotifier>();
        for ( ProjectNotifier notifier : notifiers )
        {
            // ----------------------------------------------------------------------
            // Check if the mail should be sent at all
            // ----------------------------------------------------------------------

            if ( shouldNotify( build, previousBuild, notifier ) )
            {
                notifiersList.add( notifier );
            }
        }
        buildComplete( project, notifiersList, build, previousBuild, messageId, context, buildDefinition );
    }

    private void buildComplete( Project project, List<ProjectNotifier> notifiers, BuildResult build,
                                BuildResult previousBuild, String messageId, MessageContext messageContext,
                                BuildDefinition buildDefinition )
        throws NotificationException
    {
        // ----------------------------------------------------------------------
        // Generate the mail contents
        // ----------------------------------------------------------------------

        String packageName = getClass().getPackage().getName().replace( '.', '/' );

        String templateName = packageName + "/templates/" + project.getExecutorId() + "/" + messageId + ".vm";

        StringWriter writer = new StringWriter();

        String content;

        try
        {
            VelocityContext context = new VelocityContext();

            context.put( "includeTestSummary", includeTestSummary );

            context.put( "includeOutput", includeBuildOutput );

            if ( includeBuildOutput )
            {
                context.put( "buildOutput", getBuildOutput( project, build ) );
            }

            if ( includeBuildSummary )
            {
                context.put( "build", build );

                ReportTestResult reportTestResult = reportTestSuiteGenerator.generateReportTestResult( build.getId(),
                                                                                                       project.getId() );

                context.put( "testResult", reportTestResult );

                context.put( "project", project );

                context.put( "changesSinceLastSuccess", continuum.getChangesSinceLastSuccess( project.getId(),
                                                                                              build.getId() ) );

                context.put( "previousBuild", previousBuild );

                // ----------------------------------------------------------------------
                // Tools
                // ----------------------------------------------------------------------

                context.put( "formatter", formatterTool );

                // TODO: Make the build host a part of the build

                context.put( "buildHost", buildHost );

                String osName = System.getProperty( "os.name" );

                String osPatchLevel = System.getProperty( "sun.os.patch.level" );

                if ( osPatchLevel != null )
                {
                    osName = osName + "(" + osPatchLevel + ")";
                }

                context.put( "osName", osName );

                context.put( "javaVersion", System.getProperty( "java.version" ) + "(" + System.getProperty(
                    "java.vendor" ) + ")" );

                // TODO only in case of a java project ?
                context.put( "javaHomeInformations", getJavaHomeInformations( buildDefinition ) );

                context.put( "builderVersions", getBuilderVersion( buildDefinition, project ) );
            }

            // ----------------------------------------------------------------------
            // Data objects
            // ----------------------------------------------------------------------

            context.put( "reportUrl", getReportUrl( project, build, configurationService ) );

            // TODO put other profile env var could be a security if they provide passwords ?

            // ----------------------------------------------------------------------
            // Generate
            // ----------------------------------------------------------------------

            velocity.getEngine().mergeTemplate( templateName, context, writer );

            content = writer.getBuffer().toString();
        }
        catch ( ResourceNotFoundException e )
        {
            log.info( "No such template: '" + templateName + "'." );

            return;
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail contents.", e );
        }

        // ----------------------------------------------------------------------
        // Send the mail
        // ----------------------------------------------------------------------

        String subject;
        try
        {
            subject = generateSubject( project, build );
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail subject.", e );
        }

        sendMessage( project, notifiers, subject, content, messageContext );
    }

    private void prepareBuildComplete( ProjectScmRoot projectScmRoot, List<ProjectNotifier> notifiers, String messageId,
                                       MessageContext messageContext )
        throws NotificationException
    {
        // ----------------------------------------------------------------------
        // Generate the mail contents
        // ----------------------------------------------------------------------

        String packageName = getClass().getPackage().getName().replace( '.', '/' );

        String templateName = packageName + "/templates/" + messageId + ".vm";

        StringWriter writer = new StringWriter();

        String content;

        try
        {
            VelocityContext context = new VelocityContext();

            // ----------------------------------------------------------------------
            // Data objects
            // ----------------------------------------------------------------------

            context.put( "reportUrl", getReportUrl( projectScmRoot.getProjectGroup(), projectScmRoot,
                                                    configurationService ) );

            context.put( "projectScmRoot", projectScmRoot );

            // TODO put other profile env var could be a security if they provide passwords ?

            // ----------------------------------------------------------------------
            // Generate
            // ----------------------------------------------------------------------

            velocity.getEngine().mergeTemplate( templateName, context, writer );

            content = writer.getBuffer().toString();
        }
        catch ( ResourceNotFoundException e )
        {
            log.info( "No such template: '" + templateName + "'." );

            return;
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail contents.", e );
        }

        // ----------------------------------------------------------------------
        // Send the mail
        // ----------------------------------------------------------------------

        String subject;
        try
        {
            subject = generateSubject( projectScmRoot );
        }
        catch ( Exception e )
        {
            throw new NotificationException( "Error while generating mail subject.", e );
        }

        sendMessage( projectScmRoot, notifiers, subject, content, messageContext );
    }

    // ----------------------------------------------------------------------
    //
    // ----------------------------------------------------------------------

    private List<String> getJavaHomeInformations( BuildDefinition buildDefinition )
        throws InstallationException
    {
        if ( buildDefinition == null )
        {
            return continuum.getInstallationService().getDefaultJavaVersionInfo();
        }
        Profile profile = buildDefinition.getProfile();
        if ( profile == null )
        {
            return continuum.getInstallationService().getDefaultJavaVersionInfo();
        }
        return continuum.getInstallationService().getJavaVersionInfo( profile.getJdk() );
    }

    private List<String> getBuilderVersion( BuildDefinition buildDefinition, Project project )
        throws InstallationException
    {
        ExecutorConfigurator executorConfigurator;
        Installation builder = null;
        Profile profile = null;
        if ( buildDefinition != null )
        {
            profile = buildDefinition.getProfile();
            if ( profile != null )
            {
                builder = profile.getBuilder();
            }
        }
        if ( builder != null )
        {
            executorConfigurator = continuum.getInstallationService().getExecutorConfigurator( builder.getType() );
        }
        else
        {
            // depends on ExecutorId
            if ( MavenTwoBuildExecutor.ID.equals( project.getExecutorId() ) )
            {
                executorConfigurator = continuum.getInstallationService().getExecutorConfigurator(
                    InstallationService.MAVEN2_TYPE );
            }
            else if ( MavenOneBuildExecutor.ID.equals( project.getExecutorId() ) )
            {
                executorConfigurator = continuum.getInstallationService().getExecutorConfigurator(
                    InstallationService.MAVEN1_TYPE );
            }
            else if ( AntBuildExecutor.ID.equals( project.getExecutorId() ) )
            {
                executorConfigurator = continuum.getInstallationService().getExecutorConfigurator(
                    InstallationService.ANT_TYPE );
            }
            else
            {
                return Arrays.asList( "No builder defined" );
            }
        }

        return continuum.getInstallationService().getExecutorVersionInfo(
            builder == null ? null : builder.getVarValue(), executorConfigurator, profile );
    }

    private String generateSubject( Project project, BuildResult build )
        throws Exception
    {
        String state = getState( project, build );

        VelocityContext context = new VelocityContext();
        context.put( "project", project );
        context.put( "build", build );
        context.put( "state", state );

        StringWriter writer = new StringWriter();

        boolean velocityRes = velocity.getEngine().evaluate( context, writer, "subjectPattern", buildSubjectFormat );

        return writer.toString();
    }

    private String generateSubject( ProjectScmRoot projectScmRoot )
        throws Exception
    {
        String state = getState( projectScmRoot );

        VelocityContext context = new VelocityContext();
        context.put( "projectScmRoot", projectScmRoot );
        context.put( "state", state );

        StringWriter writer = new StringWriter();

        boolean velocityResults = velocity.getEngine().evaluate( context, writer, "subjectPattern",
                                                                 prepareBuildSubjectFormat );

        return writer.toString();
    }

    private String getState( Project project, BuildResult build )
    {
        int state = project.getState();

        if ( build != null )
        {
            state = build.getState();
        }

        if ( state == ContinuumProjectState.OK )
        {
            return "SUCCESSFUL";
        }
        else if ( state == ContinuumProjectState.FAILED )
        {
            return "FAILURE";
        }
        else if ( state == ContinuumProjectState.ERROR )
        {
            return "ERROR";
        }
        else
        {
            log.warn( "Unknown build state " + state + " for project " + project.getId() );

            return "ERROR: Unknown build state " + state;
        }
    }

    private String getState( ProjectScmRoot projectScmRoot )
    {
        int state = projectScmRoot.getState();

        if ( state == ContinuumProjectState.UPDATED )
        {
            return "SUCCESSFUL";
        }
        else if ( state == ContinuumProjectState.ERROR )
        {
            return "ERROR";
        }
        else
        {
            log.warn(
                "Unknown prepare build state " + state + " for SCM Root URL " + projectScmRoot.getScmRootAddress() +
                    " in projectGroup " + projectScmRoot.getProjectGroup().getId() );

            return "ERROR: Unknown build state " + state;
        }
    }

    private void sendMessage( Project project, List<ProjectNotifier> notifiers, String subject, String content,
                              MessageContext context )
        throws NotificationException
    {
        if ( notifiers.size() == 0 )
        {
            // This is a useful message for the users when debugging why they don't
            // receive any mails

            log.info( "No mail notifier for '" + project.getName() + "'." );

            return;
        }

        String fromMailbox = getFromMailbox( notifiers );

        if ( fromMailbox == null )
        {
            log.warn( project.getName() +
                          ": Project is missing nag email and global from mailbox is missing, not sending mail." );

            return;
        }

        try
        {

            MimeMessage message = javaMailSender.createMimeMessage();

            message.addHeader( "X-Continuum-Build-Host", buildHost );

            message.addHeader( "X-Continuum-Project-Id", Integer.toString( project.getId() ) );

            message.addHeader( "X-Continuum-Project-Name", project.getName() );

            message.setSubject( subject );

            log.info( "Message Subject: '" + subject + "'." );

            message.setText( content );

            InternetAddress from = new InternetAddress( fromMailbox, fromName );

            message.setFrom( from );

            log.info( "Sending message: From '" + from + "'." );

            if ( StringUtils.isEmpty( toOverride ) )
            {
                Set<String> listRecipents = new HashSet<String>();
                for ( ProjectNotifier notifier : notifiers )
                {
                    Map<String, String> conf = notifier.getConfiguration();
                    if ( conf != null )
                    {
                        String addressField = conf.get( ADDRESS_FIELD );

                        if ( StringUtils.isNotEmpty( addressField ) )
                        {
                            String[] addresses = StringUtils.split( addressField, "," );
                            for ( String address : addresses )
                            {
                                if ( !listRecipents.contains( address.trim() ) )
                                {
                                    // [CONTINUUM-2281] Dont repeat addesss in recipents.
                                    // TODO: set a proper name
                                    InternetAddress to = new InternetAddress( address.trim() );

                                    log.info( "Recipient: To '" + to + "'." );
                                    message.addRecipient( Message.RecipientType.TO, to );
                                    listRecipents.add( address.trim() );
                                }
                            }

                        }

                        if ( context.getBuildResult() != null )
                        {
                            String committerField = (String) notifier.getConfiguration().get( COMMITTER_FIELD );
                            String developerField = (String) notifier.getConfiguration().get( DEVELOPER_FIELD );
                            // Developers constains committers.
                            if ( StringUtils.isNotEmpty( developerField ) && Boolean.parseBoolean( developerField ) )
                            {
                                List<ProjectDeveloper> developers = project.getDevelopers();
                                if ( developers == null || developers.isEmpty() )
                                {
                                    log.warn(
                                        "No developers have been configured...notifcation email will not be sent" );
                                    return;
                                }
                                Map<String, String> developerToEmailMap = mapDevelopersToRecipients( developers );
                                for ( String email : developerToEmailMap.values() )
                                {
                                    if ( !listRecipents.contains( email.trim() ) )
                                    {
                                        InternetAddress to = new InternetAddress( email.trim() );
                                        log.info( "Recipient: To '" + to + "'." );
                                        message.addRecipient( Message.RecipientType.TO, to );
                                        listRecipents.add( email.trim() );
                                    }
                                }
                            }
                            else if ( StringUtils.isNotEmpty( committerField ) && Boolean.parseBoolean(
                                committerField ) )
                            {
                                ScmResult scmResult = context.getBuildResult().getScmResult();
                                if ( scmResult != null && scmResult.getChanges() != null &&
                                    !scmResult.getChanges().isEmpty() )
                                {
                                    List<ProjectDeveloper> developers = project.getDevelopers();
                                    if ( developers == null || developers.isEmpty() )
                                    {
                                        log.warn( "No developers have been configured...notifcation email " +
                                                      "will not be sent" );
                                        return;
                                    }

                                    Map<String, String> developerToEmailMap = mapDevelopersToRecipients( developers );

                                    List<ChangeSet> changes = scmResult.getChanges();

                                    for ( ChangeSet changeSet : changes )
                                    {
                                        String scmId = changeSet.getAuthor();
                                        if ( StringUtils.isNotEmpty( scmId ) )
                                        {
                                            String email = developerToEmailMap.get( scmId );
                                            if ( StringUtils.isEmpty( email ) )
                                            {
                                                //TODO: Add a default domain so mail address won't be required
                                                log.warn(
                                                    "no email address is defined in developers list for '" + scmId +
                                                        "' scm id." );
                                            }
                                            else if ( !listRecipents.contains( email.trim() ) )
                                            {
                                                // [CONTINUUM-2281] Dont repeat addesss in recipents.)
                                                // TODO: set a proper name
                                                InternetAddress to = new InternetAddress( email.trim() );
                                                log.info( "Recipient: To '" + to + "'." );

                                                message.addRecipient( Message.RecipientType.TO, to );
                                                listRecipents.add( email.trim() );
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // TODO: use configuration file instead of to load it fron component configuration
                // TODO: set a proper name
                InternetAddress to = new InternetAddress( toOverride.trim() );
                log.info( "Recipient: To '" + to + "'." );

                message.addRecipient( Message.RecipientType.TO, to );
            }

            message.setSentDate( new Date() );

            if ( message.getAllRecipients() != null && ( message.getAllRecipients() ).length > 0 )
            {
                javaMailSender.send( message );
            }
        }
        catch ( AddressException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( MessagingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( UnsupportedEncodingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
    }

    private void sendMessage( ProjectScmRoot projectScmRoot, List<ProjectNotifier> notifiers, String subject,
                              String content, MessageContext context )
        throws NotificationException
    {
        ProjectGroup projectGroup = projectScmRoot.getProjectGroup();

        if ( notifiers.size() == 0 )
        {
            // This is a useful message for the users when debugging why they don't
            // receive any mails

            log.info( "No mail notifier for '" + projectGroup.getName() + "'." );

            return;
        }

        String fromMailbox = getFromMailbox( notifiers );

        if ( fromMailbox == null )
        {
            log.warn( projectGroup.getName() +
                          ": ProjectGroup is missing nag email and global from mailbox is missing, not sending mail." );

            return;
        }

        MimeMessage message = javaMailSender.createMimeMessage();

        try
        {
            message.setSubject( subject );

            log.info( "Message Subject: '" + subject + "'." );

            message.setText( content );

            InternetAddress from = new InternetAddress( fromMailbox, fromName );

            message.setFrom( from );

            log.info( "Sending message: From '" + from + "'." );

            if ( StringUtils.isEmpty( toOverride ) )
            {
                for ( ProjectNotifier notifier : notifiers )
                {
                    if ( !shouldNotify( projectScmRoot, notifier ) )
                    {
                        continue;
                    }

                    Map<String, String> conf = notifier.getConfiguration();
                    if ( conf != null )
                    {
                        String addressField = conf.get( ADDRESS_FIELD );

                        if ( StringUtils.isNotEmpty( addressField ) )
                        {
                            String[] addresses = StringUtils.split( addressField, "," );

                            for ( String address : addresses )
                            {
                                // TODO: set a proper name
                                InternetAddress to = new InternetAddress( address.trim() );

                                log.info( "Recipient: To '" + to + "'." );
                                message.addRecipient( Message.RecipientType.TO, to );
                            }
                        }
                    }
                }
            }
            else
            {
                // TODO: use configuration file instead of to load it fron component configuration
                // TODO: set a proper name
                InternetAddress to = new InternetAddress( toOverride.trim() );
                log.info( "Recipient: To '" + to + "'." );

                message.addRecipient( Message.RecipientType.TO, to );
            }

            message.setSentDate( new Date() );

            if ( message.getAllRecipients() != null && ( message.getAllRecipients() ).length > 0 )
            {
                javaMailSender.send( message );
            }
        }
        catch ( AddressException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( MessagingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
        catch ( UnsupportedEncodingException ex )
        {
            throw new NotificationException( "Exception while sending message.", ex );
        }
    }

    private Map<String, String> mapDevelopersToRecipients( List<ProjectDeveloper> developers )
    {
        Map<String, String> developersMap = new HashMap<String, String>();

        for ( ProjectDeveloper developer : developers )
        {
            if ( StringUtils.isNotEmpty( developer.getScmId() ) && StringUtils.isNotEmpty( developer.getEmail() ) )
            {
                developersMap.put( developer.getScmId(), developer.getEmail() );
            }
        }

        return developersMap;
    }

    private String getFromMailbox( List<ProjectNotifier> notifiers )
    {
        if ( fromMailbox != null )
        {
            return fromMailbox;
        }

        String address = null;

        for ( ProjectNotifier notifier : notifiers )
        {
            Map<String, String> configuration = notifier.getConfiguration();
            if ( configuration != null && StringUtils.isNotEmpty( configuration.get( ADDRESS_FIELD ) ) )
            {
                address = configuration.get( ADDRESS_FIELD );
                break;
            }
        }

        if ( StringUtils.isEmpty( address ) )
        {
            return FALLBACK_FROM_MAILBOX;
        }
        // olamy : CONTINUUM-860 if address contains commas we use only the first one
        if ( address != null && address.contains( "," ) )
        {
            String[] addresses = StringUtils.split( address, "," );
            return addresses[0];
        }
        return address;
    }

    public String getBuildHost()
    {
        return buildHost;
    }

    public void setBuildHost( String buildHost )
    {
        this.buildHost = buildHost;
    }

    public String getToOverride()
    {
        return toOverride;
    }

    public void setToOverride( String toOverride )
    {
        this.toOverride = toOverride;
    }
}
