package org.apache.maven.plugin.gpg;

/*
 * 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.IOException;
import java.util.List;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.codehaus.plexus.util.StringUtils;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;

/**
 * @author Benjamin Bentmann
 */
public abstract class AbstractGpgMojo
    extends AbstractMojo
{

    /**
     * The directory from which gpg will load keyrings. If not specified, gpg will use the value configured for its
     * installation, e.g. <code>~/.gnupg</code> or <code>%APPDATA%/gnupg</code>.
     *
     * @since 1.0
     */
    @Parameter( property = "gpg.homedir" )
    private File homedir;

    /**
     * The passphrase to use when signing. If not given, look up the value under Maven
     * settings using server id at 'passphraseServerKey' configuration.
     **/
    @Parameter( property = "gpg.passphrase" )
    private String passphrase;

    /**
     * Server id to lookup the passphrase under Maven settings.
     * @since 1.6
     */
    @Parameter( property = "gpg.passphraseServerId", defaultValue = "gpg.passphrase" )
    private String passphraseServerId;

    /**
     * The "name" of the key to sign with. Passed to gpg as <code>--local-user</code>.
     */
    @Parameter( property = "gpg.keyname" )
    private String keyname;

    /**
     * Passes <code>--use-agent</code> or <code>--no-use-agent</code> to gpg. If using an agent, the passphrase is
     * optional as the agent will provide it. For gpg2, specify true as --no-use-agent was removed in gpg2 and doesn't
     * ask for a passphrase anymore.
     */
    @Parameter( property = "gpg.useagent", defaultValue = "true" )
    private boolean useAgent;

    /**
     */
    @Parameter( defaultValue = "${settings.interactiveMode}", readonly = true )
    private boolean interactive;

    /**
     * The path to the GnuPG executable to use for artifact signing. Defaults to either "gpg" or "gpg.exe" depending on
     * the operating system.
     *
     * @since 1.1
     */
    @Parameter( property = "gpg.executable" )
    private String executable;

    /**
     * Whether to add the default keyrings from gpg's home directory to the list of used keyrings.
     *
     * @since 1.2
     */
    @Parameter( property = "gpg.defaultKeyring", defaultValue = "true" )
    private boolean defaultKeyring;

    /**
     * <p>The path to a secret keyring to add to the list of keyrings. By default, only the {@code secring.gpg} from 
     * gpg's home directory is considered. Use this option (in combination with {@link #publicKeyring} and
     * {@link #defaultKeyring} if required) to use a different secret key. <em>Note:</em> Relative paths are resolved
     * against gpg's home directory, not the project base directory.</p>
     * <strong>NOTE: </strong>As of gpg 2.1 this is an obsolete option and ignored. All secret keys are stored in the
     * ‘private-keys-v1.d’ directory below the GnuPG home directory.
     *
     * @since 1.2
     */
    @Parameter( property = "gpg.secretKeyring" )
    private String secretKeyring;

    /**
     * The path to a public keyring to add to the list of keyrings. By default, only the {@code pubring.gpg} from gpg's
     * home directory is considered. Use this option (and {@link #defaultKeyring} if required) to use a different public
     * key. <em>Note:</em> Relative paths are resolved against gpg's home directory, not the project base directory.
     *
     * @since 1.2
     */
    @Parameter( property = "gpg.publicKeyring" )
    private String publicKeyring;

    /**
     * The lock mode to use when invoking gpg. By default no lock mode will be specified. Valid values are {@code once},
     * {@code multiple} and {@code never}. The lock mode gets translated into the corresponding {@code --lock-___}
     * command line argument. Improper usage of this option may lead to data and key corruption.
     *
     * @see <a href="http://www.gnupg.org/documentation/manuals/gnupg/GPG-Configuration-Options.html">the
     *      --lock-options</a>
     * @since 1.5
     */
    @Parameter( property = "gpg.lockMode" )
    private String lockMode;

    /**
     * Sets the arguments to be passed to gpg. Example:
     *
     * <pre>
     * &lt;gpgArguments&gt;
     *   &lt;arg&gt;--no-random-seed-file&lt;/arg&gt;
     *   &lt;arg&gt;--no-permission-warning&lt;/arg&gt;
     * &lt;/gpgArguments&gt;
     * </pre>
     *
     * @since 1.5
     */
    @Parameter
    private List<String> gpgArguments;

    /**
     * Current user system settings for use in Maven.
     *
     * @since 1.6
     */
    @Parameter( defaultValue = "${settings}", readonly = true )
    private Settings settings;

    /**
     * Maven Security Dispatcher
     *
     * @since 1.6
     */
    @Component( hint = "mng-4384" )
    private SecDispatcher securityDispatcher;

    AbstractGpgSigner newSigner( MavenProject project )
        throws MojoExecutionException, MojoFailureException
    {
        AbstractGpgSigner signer = new GpgSigner( executable );

        signer.setLog( getLog() );
        signer.setInteractive( interactive );
        signer.setKeyName( keyname );
        signer.setUseAgent( useAgent );
        signer.setHomeDirectory( homedir );
        signer.setDefaultKeyring( defaultKeyring );
        signer.setSecretKeyring( secretKeyring );
        signer.setPublicKeyring( publicKeyring );
        signer.setLockMode( lockMode );
        signer.setArgs( gpgArguments );

        loadGpgPassphrase();

        signer.setPassPhrase( passphrase );
        if ( null == passphrase && !useAgent )
        {
            if ( !interactive )
            {
                throw new MojoFailureException( "Cannot obtain passphrase in batch mode" );
            }
            try
            {
                signer.setPassPhrase( signer.getPassphrase( project ) );
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Exception reading passphrase", e );
            }
        }

        return signer;
    }

    /**
     * Load and decrypt gpg passphrase from Maven settings if not given from plugin configuration
     *
     * @throws MojoFailureException
     */
    private void loadGpgPassphrase()
        throws MojoFailureException
    {
        if ( StringUtils.isEmpty( this.passphrase ) )
        {
            Server server = this.settings.getServer( passphraseServerId );

            if ( server != null )
            {
                if ( server.getPassphrase() != null )
                {
                    try
                    {
                        this.passphrase = securityDispatcher.decrypt( server.getPassphrase() );
                    }
                    catch ( SecDispatcherException e )
                    {
                        throw new MojoFailureException( "Unable to decrypt gpg passphrase", e );
                    }
                }
            }
        }
    }
}
