package org.apache.maven.plugins.announcement;

/*
 * 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 java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import org.apache.maven.model.Developer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.announcement.mailsender.ProjectJavamailMailSender;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.mailsender.MailMessage;
import org.codehaus.plexus.mailsender.MailSenderException;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;

/**
 * Goal which sends an announcement through email.
 *
 * @author aramirez@exist.com
 * @version $Id$
 * @since 2.0-beta-2
 */
@Mojo( name = "announcement-mail", threadSafe = true )
@Execute( goal = "announcement-generate" )
public class AnnouncementMailMojo
    extends AbstractAnnouncementMojo
{
    // =========================================
    // announcement-mail goal fields
    // =========================================

    /**
     * Possible senders.
     */
    @Parameter( property = "project.developers", required = true, readonly = true )
    private List<Developer> from;

    /**
     * The id of the developer sending the announcement mail. Only used if the <tt>mailSender</tt> attribute is not set.
     * In this case, this should match the id of one of the developers in the pom. If a matching developer is not found,
     * then the first developer in the pom will be used.
     */
    @Parameter( property = "changes.fromDeveloperId" )
    private String fromDeveloperId;

    /**
     * Mail content type to use.
     *
     * @since 2.1
     */
    @Parameter( defaultValue = "text/plain", required = true )
    private String mailContentType;

    /**
     * Defines the sender of the announcement email. This takes precedence over the list of developers specified in the
     * POM. if the sender is not a member of the development team. Note that since this is a bean type, you cannot
     * specify it from command level with
     * 
     * <pre>
     * -D
     * </pre>
     * 
     * . Use
     * 
     * <pre>
     * -Dchanges.sender='Your Name &lt;you@domain>'
     * </pre>
     * 
     * instead.
     */
    @Parameter( property = "changes.mailSender" )
    private MailSender mailSender;

    /**
     * Defines the sender of the announcement. This takes precedence over both ${changes.mailSender} and the list of
     * developers in the POM.
     * <p/>
     * This parameter parses an email address in standard RFC822 format, e.g.
     * 
     * <pre>
     * -Dchanges.sender='Your Name &lt;you@domain>'
     * </pre>
     * 
     * .
     *
     * @since 2.7
     */
    @Parameter( property = "changes.sender" )
    private String senderString;

    /**
     * The password used to send the email.
     */
    @Parameter( property = "changes.password" )
    private String password;

    /**
     */
    @Parameter( defaultValue = "${project}", readonly = true, required = true )
    private MavenProject project;

    /**
     * Smtp Server.
     */
    @Parameter( property = "changes.smtpHost", required = true )
    private String smtpHost;

    /**
     * Port.
     */
    @Parameter( property = "changes.smtpPort", defaultValue = "25", required = true )
    private int smtpPort;

    /**
     * If the email should be sent in SSL mode.
     */
    @Parameter( property = "changes.sslMode", defaultValue = "false" )
    private boolean sslMode;

    /**
     * If the option startTls should be used.
     *
     * @since 2.10
     */
    @Parameter( property = "changes.startTls", defaultValue = "false" )
    private boolean startTls;

    /**
     * Subject for the email.
     */
    // CHECKSTYLE_OFF: LineLength
    @Parameter( property = "changes.subject", defaultValue = "[ANNOUNCEMENT] - ${project.name} ${project.version} released", required = true )
    private String subject;
    // CHECKSTYLE_ON: LineLength

    /**
     * The file that contains the generated announcement.
     *
     * @since 2.10
     */
    @Parameter( property = "changes.announcementFile", defaultValue = "announcement.vm", required = true )
    private String announcementFile;

    /**
     * Directory where the generated announcement file exists.
     *
     * @since 2.10
     */
    @Parameter( defaultValue = "${project.build.directory}/announcement", required = true )
    private File announcementDirectory;

    /**
     * The encoding used in the announcement template.
     *
     * @since 2.10
     */
    @Parameter( property = "changes.templateEncoding", defaultValue = "${project.build.sourceEncoding}" )
    private String templateEncoding;

    /**
     * Directory which contains the template for announcement email.
     *
     * @deprecated Starting with version 2.10 this parameter is no longer used. You must use
     *             {@link #announcementDirectory} instead.
     */
    @Parameter
    private File templateOutputDirectory;

    /**
     * Recipient email address.
     */
    @Parameter( required = true )
    private List<Object> toAddresses;

    /**
     * Recipient cc email address.
     *
     * @since 2.5
     */
    @Parameter
    private List<Object> ccAddresses;

    /**
     * Recipient bcc email address.
     *
     * @since 2.5
     */
    @Parameter
    private List<Object> bccAddresses;

    /**
     * The username used to send the email.
     */
    @Parameter( property = "changes.username" )
    private String username;

    private ProjectJavamailMailSender mailer = new ProjectJavamailMailSender();

    public void execute()
        throws MojoExecutionException
    {
        // Fail build fast if it is using deprecated parameters
        if ( templateOutputDirectory != null )
        {
            throw new MojoExecutionException( "You are using the old parameter 'templateOutputDirectory'. "
                + "You must use 'announcementDirectory' instead." );
        }

        // Run only at the execution root
        if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
        {
            getLog().info( "Skipping the announcement mail in this project because it's not the Execution Root" );
        }
        else
        {
            File file = new File( announcementDirectory, announcementFile );

            ConsoleLogger logger = new ConsoleLogger( Logger.LEVEL_INFO, "base" );

            if ( getLog().isDebugEnabled() )
            {
                logger.setThreshold( Logger.LEVEL_DEBUG );
            }

            mailer.enableLogging( logger );

            mailer.setSmtpHost( getSmtpHost() );

            mailer.setSmtpPort( getSmtpPort() );

            mailer.setSslMode( sslMode, startTls );

            if ( username != null )
            {
                mailer.setUsername( username );
            }

            if ( password != null )
            {
                mailer.setPassword( password );
            }

            mailer.initialize();

            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( "fromDeveloperId: " + getFromDeveloperId() );
            }

            if ( file.isFile() )
            {
                getLog().info( "Connecting to Host: " + getSmtpHost() + ":" + getSmtpPort() );

                sendMessage();
            }
            else
            {
                throw new MojoExecutionException( "Announcement file " + file + " not found..." );
            }
        }
    }

    /**
     * Send the email.
     *
     * @throws MojoExecutionException if the mail could not be sent
     */
    protected void sendMessage()
        throws MojoExecutionException
    {
        File file = new File( announcementDirectory, announcementFile );
        String email = "";
        final MailSender ms = getActualMailSender();
        final String fromName = ms.getName();
        final String fromAddress = ms.getEmail();
        if ( fromAddress == null || fromAddress.equals( "" ) )
        {
            throw new MojoExecutionException( "Invalid mail sender: name and email is mandatory (" + ms + ")." );
        }
        getLog().info( "Using this sender for email announcement: " + fromAddress + " < " + fromName + " > " );
        try
        {
            MailMessage mailMsg = new MailMessage();
            mailMsg.setSubject( getSubject() );
            mailMsg.setContent( readAnnouncement( file ) );
            mailMsg.setContentType( this.mailContentType );
            mailMsg.setFrom( fromAddress, fromName );

            for ( Object o1 : getToAddresses() )
            {
                email = o1.toString();
                getLog().info( "Sending mail to " + email + "..." );
                mailMsg.addTo( email, "" );
            }

            if ( getCcAddresses() != null )
            {
                for ( Object o : getCcAddresses() )
                {
                    email = o.toString();
                    getLog().info( "Sending cc mail to " + email + "..." );
                    mailMsg.addCc( email, "" );
                }
            }

            if ( getBccAddresses() != null )
            {
                for ( Object o : getBccAddresses() )
                {
                    email = o.toString();
                    getLog().info( "Sending bcc mail to " + email + "..." );
                    mailMsg.addBcc( email, "" );
                }
            }

            mailer.send( mailMsg );
            getLog().info( "Sent..." );
        }
        catch ( MailSenderException e )
        {
            throw new MojoExecutionException( "Failed to send email < " + email + " >", e );
        }
    }

    /**
     * Read the content of the generated announcement file.
     *
     * @param file the file to be read
     * @return Return the announcement text
     * @throws MojoExecutionException if the file could not be found, or if the encoding is unsupported
     */
    protected String readAnnouncement( File file )
        throws MojoExecutionException
    {
        InputStreamReader reader = null;
        try
        {
            if ( StringUtils.isEmpty( templateEncoding ) )
            {
                templateEncoding = ReaderFactory.FILE_ENCODING;
                getLog().warn( "File encoding has not been set, using platform encoding '" + templateEncoding
                                   + "', i.e. build is platform dependent!" );

            }

            reader = new InputStreamReader( new FileInputStream( file ), templateEncoding );
            final String announcement = IOUtil.toString( reader );
            reader.close();
            reader = null;
            return announcement;
        }
        catch ( FileNotFoundException fnfe )
        {
            throw new MojoExecutionException( "File not found. " + file );
        }
        catch ( UnsupportedEncodingException uee )
        {
            throw new MojoExecutionException( "Unsupported encoding: '" + templateEncoding + "'" );
        }
        catch ( IOException ioe )
        {
            throw new MojoExecutionException( "Failed to read the announcement file.", ioe );
        }
        finally
        {
            IOUtil.close( reader );
        }
    }

    /**
     * Returns the identify of the mail sender according to the plugin's configuration:
     * <ul>
     * <li>if the <tt>mailSender</tt> parameter is set, it is returned</li>
     * <li>if no <tt>fromDeveloperId</tt> is set, the first developer in the list is returned</li>
     * <li>if a <tt>fromDeveloperId</tt> is set, the developer with that id is returned</li>
     * <li>if the developers list is empty or if the specified id does not exist, an exception is thrown</li>
     * </ul>
     *
     * @return the mail sender to use
     * @throws MojoExecutionException if the mail sender could not be retrieved
     */
    protected MailSender getActualMailSender()
        throws MojoExecutionException
    {
        if ( senderString != null )
        {
            try
            {
                InternetAddress ia = new InternetAddress( senderString, true );
                return new MailSender( ia.getPersonal(), ia.getAddress() );
            }
            catch ( AddressException e )
            {
                throw new MojoExecutionException( "Invalid value for change.sender: ", e );
            }
        }
        if ( mailSender != null && mailSender.getEmail() != null )
        {
            return mailSender;
        }
        else if ( from == null || from.isEmpty() )
        {
            throw new MojoExecutionException( "The <developers> section in your pom should not be empty. "
                + "Add a <developer> entry or set the mailSender parameter." );
        }
        else if ( fromDeveloperId == null )
        {
            final Developer dev = from.get( 0 );
            return new MailSender( dev.getName(), dev.getEmail() );
        }
        else
        {
            for ( Developer developer : from )
            {
                if ( fromDeveloperId.equals( developer.getId() ) )
                {
                    return new MailSender( developer.getName(), developer.getEmail() );
                }
            }
            throw new MojoExecutionException( "Missing developer with id '" + fromDeveloperId
                + "' in the <developers> section in your pom." );
        }
    }

    // ================================
    // announcement-mail accessors
    // ================================

    public List<Object> getBccAddresses()
    {
        return bccAddresses;
    }

    public void setBccAddresses( List<Object> bccAddresses )
    {
        this.bccAddresses = bccAddresses;
    }

    public List<Object> getCcAddresses()
    {
        return ccAddresses;
    }

    public void setCcAddresses( List<Object> ccAddresses )
    {
        this.ccAddresses = ccAddresses;
    }

    public List<Developer> getFrom()
    {
        return from;
    }

    public void setFrom( List<Developer> from )
    {
        this.from = from;
    }

    public String getFromDeveloperId()
    {
        return fromDeveloperId;
    }

    public void setFromDeveloperId( String fromDeveloperId )
    {
        this.fromDeveloperId = fromDeveloperId;
    }

    public MailSender getMailSender()
    {
        return mailSender;
    }

    public void setMailSender( MailSender mailSender )
    {
        this.mailSender = mailSender;
    }

    public String getPassword()
    {
        return password;
    }

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

    public MavenProject getProject()
    {
        return project;
    }

    public void setProject( MavenProject project )
    {
        this.project = project;
    }

    public String getSmtpHost()
    {
        return smtpHost;
    }

    public void setSmtpHost( String smtpHost )
    {
        this.smtpHost = smtpHost;
    }

    public int getSmtpPort()
    {
        return smtpPort;
    }

    public void setSmtpPort( int smtpPort )
    {
        this.smtpPort = smtpPort;
    }

    public boolean isSslMode()
    {
        return sslMode;
    }

    public void setSslMode( boolean sslMode )
    {
        this.sslMode = sslMode;
    }

    public boolean isStartTls()
    {
        return startTls;
    }

    public void setStartTls( boolean startTls )
    {
        this.startTls = startTls;
    }

    public String getSubject()
    {
        return subject;
    }

    public void setSubject( String subject )
    {
        this.subject = subject;
    }

    public String getAnnouncementFile()
    {
        return announcementFile;
    }

    public void setAnnouncementFile( String announcementFile )
    {
        this.announcementFile = announcementFile;
    }

    public File getAnnouncementDirectory()
    {
        return announcementDirectory;
    }

    public void setAnnouncementDirectory( File announcementDirectory )
    {
        this.announcementDirectory = announcementDirectory;
    }

    public List<Object> getToAddresses()
    {
        return toAddresses;
    }

    public void setToAddresses( List<Object> toAddresses )
    {
        this.toAddresses = toAddresses;
    }

    public String getUsername()
    {
        return username;
    }

    public void setUsername( String username )
    {
        this.username = username;
    }
}
