package org.apache.tomcat.maven.plugin.tomcat6;

/*
 * 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.maven.artifact.manager.WagonManager;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.settings.Proxy;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.tomcat.maven.common.deployer.TomcatManager;
import org.apache.tomcat.maven.common.deployer.TomcatManagerException;
import org.codehaus.plexus.util.StringUtils;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.StringTokenizer;

/**
 * Abstract goal that provides common configuration for Catalina-based goals.
 *
 * @author Mark Hobson <markhobson@gmail.com>
 */
public abstract class AbstractCatalinaMojo
    extends AbstractI18NTomcat6Mojo
{
    // ----------------------------------------------------------------------
    // Constants
    // ----------------------------------------------------------------------

    /**
     * The name of this Maven plugin. Used to produce the user agent when communicating with Tomcat manager.
     */
    private String name = "Apache Tomcat Maven Plugin";

    /**
     * The default username to use when authenticating with Tomcat manager.
     */
    private static final String DEFAULT_USERNAME = "admin";

    /**
     * The default password to use when authenticating with Tomcat manager.
     */
    private static final String DEFAULT_PASSWORD = "";

    // ----------------------------------------------------------------------
    // Mojo Parameters
    // ----------------------------------------------------------------------

    /**
     * The Maven Wagon manager to use when obtaining server authentication details.
     */
    @Component( role = WagonManager.class )
    private WagonManager wagonManager;

    /**
     * The current build session instance. This is used for plugin manager API calls.
     */
    @Component
    private MavenSession session;

    /**
     * The full URL of the Tomcat manager instance to use.
     */
    @Parameter( property = "maven.tomcat.url", defaultValue = "http://localhost:8080/manager", required = true )
    private URL url;

    /**
     * The server id in settings.xml to use when authenticating with Tomcat manager, or <code>null</code> to use
     * defaults of username <code>admin</code> and no password.
     */
    @Parameter( property = "maven.tomcat.server" )
    private String server;

    /**
     * The URL encoding charset to use when communicating with Tomcat manager.
     */
    @Parameter( property = "maven.tomcat.charset", defaultValue = "ISO-8859-1", required = true )
    private String charset;

    /**
     * The tomcat username to use for deployment
     *
     * @since 1.0-alpha-2
     */
    @Parameter( property = "tomcat.username" )
    private String username;

    /**
     * The password to use for deployment
     *
     * @since 1.0-alpha-2
     */
    @Parameter( property = "tomcat.password" )
    private String password;

    @Parameter( property = "plugin.version", required = true, readonly = true )
    private String version;

    /**
     * Skip the execution.
     *
     * @since 2.3
     */
    @Parameter( property = "maven.tomcat.skip", defaultValue = "false" )
    private boolean skip;

    // ----------------------------------------------------------------------
    // Fields
    // ----------------------------------------------------------------------

    /**
     * The Tomcat manager wrapper object.
     */
    private TomcatManager manager;

    // ----------------------------------------------------------------------
    // Mojo Implementation
    // ----------------------------------------------------------------------

    /**
     * {@inheritDoc}
     */
    public void execute()
        throws MojoExecutionException
    {
        if ( this.skip )
        {
            getLog().info( "skip execution" );
            return;
        }

        try
        {
            invokeManager();
        }
        catch ( TomcatManagerException exception )
        {
            throw new MojoExecutionException(
                messagesProvider.getMessage( "AbstractCatalinaMojo.managerError", exception.getMessage() ) );
        }
        catch ( IOException exception )
        {
            throw new MojoExecutionException( messagesProvider.getMessage( "AbstractCatalinaMojo.managerIOError" ),
                                              exception );
        }
    }

    // ----------------------------------------------------------------------
    // Protected Methods
    // ----------------------------------------------------------------------

    /**
     * Invokes Tomcat manager when this Mojo is executed.
     *
     * @throws MojoExecutionException if there was a problem executing this goal
     * @throws TomcatManagerException if the Tomcat manager request fails
     * @throws IOException            if an i/o error occurs
     */
    protected abstract void invokeManager()
        throws MojoExecutionException, TomcatManagerException, IOException;

    /**
     * Gets the Tomcat manager wrapper object configured for this goal.
     *
     * @return the Tomcat manager wrapper object
     * @throws MojoExecutionException if there was a problem obtaining the authentication details
     */
    protected TomcatManager getManager()
        throws MojoExecutionException
    {
        // lazily instantiate when config values have been injected
        if ( manager == null )
        {
            String userName;
            String password;

            if ( server == null )
            {
                // no server set, use defaults
                getLog().debug( messagesProvider.getMessage( "AbstractCatalinaMojo.defaultAuth" ) );
                userName = DEFAULT_USERNAME;
                password = DEFAULT_PASSWORD;
            }
            else
            {
                // obtain authenication details for specified server from wagon
                AuthenticationInfo info = wagonManager.getAuthenticationInfo( server );
                if ( info == null )
                {
                    throw new MojoExecutionException(
                        messagesProvider.getMessage( "AbstractCatalinaMojo.unknownServer", server ) );
                }

                // derive username
                userName = info.getUserName();
                if ( userName == null )
                {
                    getLog().debug( messagesProvider.getMessage( "AbstractCatalinaMojo.defaultUserName" ) );
                    userName = DEFAULT_USERNAME;
                }

                // derive password
                password = info.getPassword();
                if ( password == null )
                {
                    getLog().debug( messagesProvider.getMessage( "AbstractCatalinaMojo.defaultPassword" ) );
                    password = DEFAULT_PASSWORD;
                }
            }

            // if userName/password are defined in the mojo or the cli they override
            if ( !StringUtils.isEmpty( this.username ) )
            {
                userName = this.username;
                password = this.password == null ? "" : this.password;
                //getLog( ).debug( "user user/password " + userName + "/" + password );
            }

            manager = new TomcatManager( url, userName, password, charset, settings.isInteractiveMode() );
            manager.setUserAgent( name + "/" + version );

            Proxy proxy = session.getSettings().getActiveProxy();
            if ( proxy != null && proxy.isActive() )
            {
                getLog().debug( "proxy: " + proxy.getHost() + ":" + proxy.getPort() );
                manager.setProxy( proxy );
            }
        }

        return manager;
    }

    /**
     * Gets the full URL of the Tomcat manager instance.
     *
     * @return the full URL of the Tomcat manager instance to use
     */
    protected URL getURL()
    {
        return url;
    }

    /**
     * Gets the webapp context path to use when communicating with Tomcat manager.
     *
     * @return the webapp context path to use
     */
    protected String getPath()
    {
        return path;
    }

    /**
     * Gets the URL of the deployed webapp.
     *
     * @return the URL of the deployed webapp
     * @throws MalformedURLException if the deployed webapp URL is invalid
     */
    protected URL getDeployedURL()
        throws MalformedURLException
    {
        return new URL( getURL(), getPath() );
    }

    /**
     * Splits the given string into lines and writes each one separately to the log at info level.
     *
     * @param string the string to write
     */
    protected void log( String string )
    {
        StringTokenizer tokenizer = new StringTokenizer( string, "\n\r" );

        while ( tokenizer.hasMoreTokens() )
        {
            getLog().info( tokenizer.nextToken() );
        }
    }
}
