package org.apache.tomcat.maven.runner;
/*
 * 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.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;

/**
 * @author Olivier Lamy
 * @since 2.0
 */
@SuppressWarnings("static-access")
public class Tomcat7RunnerCli
{

    public static final String STAND_ALONE_PROPERTIES_FILENAME = "tomcat.standalone.properties";

    static Option httpPort =
        OptionBuilder.withArgName( "httpPort" ).hasArg().withDescription( "http port to use" ).create( "httpPort" );

    static Option httpsPort =
        OptionBuilder.withArgName( "httpsPort" ).hasArg().withDescription( "https port to use" ).create( "httpsPort" );

    static Option maxPostSize =
        OptionBuilder.withArgName( "maxPostSize" ).hasArg().withDescription( "max post size to use" ).create(
            "maxPostSize" );

    static Option ajpPort =
        OptionBuilder.withArgName( "ajpPort" ).hasArg().withDescription( "ajp port to use" ).create( "ajpPort" );

    static Option serverXmlPath =
        OptionBuilder.withArgName( "serverXmlPath" ).hasArg().withDescription( "server.xml to use, optional" ).create(
            "serverXmlPath" );

    static Option resetExtract =
        OptionBuilder.withArgName( "resetExtract" ).withDescription( "clean previous extract directory" ).create(
            "resetExtract" );

    static Option help = OptionBuilder.withLongOpt( "help" ).withDescription( "help" ).create( 'h' );

    static Option debug = OptionBuilder.withLongOpt( "debug" ).withDescription( "debug" ).create( 'X' );

    static Option sysProps = OptionBuilder.withDescription( "use value for given property" ).hasArgs().withDescription(
        "key=value" ).withValueSeparator().create( 'D' );

    static Option clientAuth =
        OptionBuilder.withArgName( "clientAuth" ).withDescription( "enable client authentication for https" ).create(
            "clientAuth" );

    static Option keyAlias =
        OptionBuilder.withArgName( "keyAlias" ).hasArgs().withDescription( "alias from keystore for ssl" ).create(
            "keyAlias" );

    static Option obfuscate =
        OptionBuilder.withArgName( "password" ).hasArgs().withDescription( "obfuscate the password and exit" ).create(
            "obfuscate" );

    static Option httpProtocol = OptionBuilder.withArgName( "httpProtocol" ).hasArg().withDescription(
        "http protocol to use: HTTP/1.1 or org.apache.coyote.http11.Http11NioProtocol" ).create( "httpProtocol" );

    static Option extractDirectory = OptionBuilder.withArgName( "extractDirectory" ).hasArg().withDescription(
        "path to extract war content, default value: .extract" ).create( "extractDirectory" );

    static Option sessionManagerFactoryClassName = OptionBuilder.withArgName( "className" ).hasArg().withDescription(
        "classname of a factory that creates a session manager" ).create( "sessionManagerFactory" );


    static Option loggerName = OptionBuilder.withArgName( "loggerName" ).hasArg().withDescription(
        "logger to use: slf4j to use slf4j bridge on top of jul" ).create( "loggerName" );

    static Option uriEncoding = OptionBuilder.withArgName( "uriEncoding" ).hasArg().withDescription(
        "connector uriEncoding default ISO-8859-1" ).create( "uriEncoding" );

    static Options options = new Options();

    static
    {
        options.addOption( httpPort ) //
            .addOption( httpsPort ) //
            .addOption( ajpPort ) //
            .addOption( serverXmlPath ) //
            .addOption( resetExtract ) //
            .addOption( help ) //
            .addOption( debug ) //
            .addOption( sysProps ) //
            .addOption( httpProtocol ) //
            .addOption( clientAuth ) //
            .addOption( keyAlias ) //
            .addOption( obfuscate ) //
            .addOption( extractDirectory ) //
            .addOption( sessionManagerFactoryClassName ) //
            .addOption( loggerName ) //
            .addOption( uriEncoding ) //
            .addOption( maxPostSize );
    }


    public static void main( String[] args )
        throws Exception
    {
        CommandLineParser parser = new GnuParser();
        CommandLine line = null;
        try
        {
            line = parser.parse( Tomcat7RunnerCli.options, args );
        }
        catch ( ParseException e )
        {
            System.err.println( "Parsing failed.  Reason: " + e.getMessage() );
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp( getCmdLineSyntax(), Tomcat7RunnerCli.options );
            System.exit( 1 );
        }

        if ( line.hasOption( help.getOpt() ) )
        {
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp( getCmdLineSyntax(), Tomcat7RunnerCli.options );
            System.exit( 0 );
        }

        if ( line.hasOption( obfuscate.getOpt() ) )
        {
            System.out.println( PasswordUtil.obfuscate( line.getOptionValue( obfuscate.getOpt() ) ) );
            System.exit( 0 );
        }
        Tomcat7Runner tomcat7Runner = new Tomcat7Runner();

        tomcat7Runner.runtimeProperties = buildStandaloneProperties();

        if ( line.hasOption( serverXmlPath.getOpt() ) )
        {
            tomcat7Runner.serverXmlPath = line.getOptionValue( serverXmlPath.getOpt() );
        }

        String port = tomcat7Runner.runtimeProperties.getProperty( Tomcat7Runner.HTTP_PORT_KEY );
        if ( port != null )
        {
            tomcat7Runner.httpPort = Integer.parseInt( port );
        }

        // cli win for the port
        if ( line.hasOption( httpPort.getOpt() ) )
        {
            tomcat7Runner.httpPort = Integer.parseInt( line.getOptionValue( httpPort.getOpt() ) );
        }

        if ( line.hasOption( maxPostSize.getOpt() ) )
        {
            tomcat7Runner.maxPostSize = Integer.parseInt( line.getOptionValue( maxPostSize.getOpt() ) );
        }

        if ( line.hasOption( httpsPort.getOpt() ) )
        {
            tomcat7Runner.httpsPort = Integer.parseInt( line.getOptionValue( httpsPort.getOpt() ) );
        }
        if ( line.hasOption( ajpPort.getOpt() ) )
        {
            tomcat7Runner.ajpPort = Integer.parseInt( line.getOptionValue( ajpPort.getOpt() ) );
        }
        if ( line.hasOption( resetExtract.getOpt() ) )
        {
            tomcat7Runner.resetExtract = true;
        }
        if ( line.hasOption( debug.getOpt() ) )
        {
            tomcat7Runner.debug = true;
        }

        if ( line.hasOption( httpProtocol.getOpt() ) )
        {
            tomcat7Runner.httpProtocol = line.getOptionValue( httpProtocol.getOpt() );
        }

        if ( line.hasOption( sysProps.getOpt() ) )
        {
            Properties systemProperties = line.getOptionProperties( sysProps.getOpt() );
            if ( systemProperties != null && !systemProperties.isEmpty() )
            {
                for ( Map.Entry<Object, Object> sysProp : systemProperties.entrySet() )
                {
                    System.setProperty( (String) sysProp.getKey(), (String) sysProp.getValue() );
                }
            }
        }
        if ( line.hasOption( clientAuth.getOpt() ) )
        {
            tomcat7Runner.clientAuth = clientAuth.getOpt();
        }
        if ( line.hasOption( keyAlias.getOpt() ) )
        {
            tomcat7Runner.keyAlias = line.getOptionValue( keyAlias.getOpt() );
        }

        if ( line.hasOption( extractDirectory.getOpt() ) )
        {
            tomcat7Runner.extractDirectory = line.getOptionValue( extractDirectory.getOpt() );
        }

        if ( line.hasOption( sessionManagerFactoryClassName.getOpt() ) )
        {
            tomcat7Runner.sessionManagerFactoryClassName =
                line.getOptionValue( sessionManagerFactoryClassName.getOpt() );
        }

        if ( line.hasOption( loggerName.getOpt() ) )
        {
            tomcat7Runner.loggerName = line.getOptionValue( loggerName.getOpt() );
        }

        if ( line.hasOption( uriEncoding.getOpt() ) )
        {
            tomcat7Runner.uriEncoding = line.getOptionValue( uriEncoding.getOpt() );
        }

        // here we go
        tomcat7Runner.run();
    }

    private static Properties buildStandaloneProperties()
        throws IOException
    {
        InputStream is =
            Thread.currentThread().getContextClassLoader().getResourceAsStream( STAND_ALONE_PROPERTIES_FILENAME );
        Properties properties = new Properties();
        properties.load( is );
        return properties;
    }

    public static String getCmdLineSyntax()
    {
        return "java -jar [path to your exec war jar]";
    }
}
