package org.apache.maven.it;

/*
 * 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.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.maven.shared.utils.io.IOUtil;

/**
 * Launches an embedded Maven 3.x instance from some Maven installation directory.
 * 
 * @author Benjamin Bentmann
 */
class Embedded3xLauncher
    implements MavenLauncher
{

    private final Object mavenCli;

    private final Method doMain;

    private Embedded3xLauncher( Object mavenCli, Method doMain )
    {
        this.mavenCli = mavenCli;
        this.doMain = doMain;
    }

    /**
     * Launches an embedded Maven 3.x instance from some Maven installation directory.
     */
    public static Embedded3xLauncher createFromMavenHome( String mavenHome, String classworldConf, List<URL> classpath )
        throws LauncherException
    {
        if ( mavenHome == null || mavenHome.length() <= 0 )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome );
        }

        System.setProperty( "maven.home", mavenHome );

        File config;
        if ( classworldConf != null )
        {
            config = new File( classworldConf );
        }
        else
        {
            config = new File( mavenHome, "bin/m2.conf" );
        }

        ClassLoader bootLoader = getBootLoader( mavenHome, classpath );

        ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader( bootLoader );
        try
        {
            Class<?> launcherClass = bootLoader.loadClass( "org.codehaus.plexus.classworlds.launcher.Launcher" );

            Object launcher = launcherClass.newInstance();

            Method configure = launcherClass.getMethod( "configure", new Class[] { InputStream.class } );

            configure.invoke( launcher, new Object[] { new FileInputStream( config ) } );

            Method getWorld = launcherClass.getMethod( "getWorld", (Class<?>) null );
            Object classWorld = getWorld.invoke( launcher, (Class<?>) null );

            Method getMainClass = launcherClass.getMethod( "getMainClass", (Class<?>) null );
            Class<?> cliClass = (Class<?>) getMainClass.invoke( launcher, (Class<?>) null );

            Constructor<?> newMavenCli = cliClass.getConstructor( new Class[] { classWorld.getClass() } );
            Object mavenCli = newMavenCli.newInstance( new Object[] { classWorld } );

            Class<?>[] parameterTypes = { String[].class, String.class, PrintStream.class, PrintStream.class };
            Method doMain = cliClass.getMethod( "doMain", parameterTypes );

            return new Embedded3xLauncher( mavenCli, doMain );
        }
        catch ( ReflectiveOperationException | IOException e )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
        }
        finally
        {
            Thread.currentThread().setContextClassLoader( oldClassLoader );
        }
    }

    /**
     * Launches an embedded Maven 3.x instance from the current class path, i.e. the Maven 3.x dependencies are assumed
     * to be present on the class path.
     */
    public static Embedded3xLauncher createFromClasspath()
        throws LauncherException
    {
        ClassLoader coreLoader = Thread.currentThread().getContextClassLoader();

        try
        {
            Class<?> cliClass = coreLoader.loadClass( "org.apache.maven.cli.MavenCli" );

            Object mavenCli = cliClass.newInstance();

            Class<?>[] parameterTypes = { String[].class, String.class, PrintStream.class, PrintStream.class };
            Method doMain = cliClass.getMethod( "doMain", parameterTypes );

            return new Embedded3xLauncher( mavenCli, doMain );
        }
        catch ( ReflectiveOperationException e )
        {
            throw new LauncherException( e.getMessage(), e );
        }
    }

    private static ClassLoader getBootLoader( String mavenHome, List<URL> classpath )
    {
        List<URL> urls = classpath;

        if ( urls == null )
        {
            urls = new ArrayList<URL>();

            File bootDir = new File( mavenHome, "boot" );
            addUrls( urls, bootDir );
        }

        if ( urls.isEmpty() )
        {
            throw new IllegalArgumentException( "Invalid Maven home directory " + mavenHome );
        }

        URL[] ucp = (URL[]) urls.toArray( new URL[urls.size()] );

        return new URLClassLoader( ucp, ClassLoader.getSystemClassLoader().getParent() );
    }

    private static void addUrls( List<URL> urls, File directory )
    {
        File[] jars = directory.listFiles();

        if ( jars != null )
        {
            for ( int i = 0; i < jars.length; i++ )
            {
                File jar = jars[i];

                if ( jar.getName().endsWith( ".jar" ) )
                {
                    try
                    {
                        urls.add( jar.toURI().toURL() );
                    }
                    catch ( MalformedURLException e )
                    {
                        throw (RuntimeException) new IllegalStateException().initCause( e );
                    }
                }
            }
        }
    }

    public int run( String[] cliArgs, Properties systemProperties, String workingDirectory, File logFile )
        throws IOException, LauncherException
    {
        PrintStream out = ( logFile != null ) ? new PrintStream( new FileOutputStream( logFile ) ) : System.out;
        try
        {
            Properties originalProperties = System.getProperties();
            System.setProperties( null );
            System.setProperty( "maven.home", originalProperties.getProperty( "maven.home", "" ) );
            System.setProperty( "user.dir", new File( workingDirectory ).getAbsolutePath() );

            for ( Object o : systemProperties.keySet() )
            {
                String key = (String) o;
                String value = systemProperties.getProperty( key );
                System.setProperty( key, value );
            }

            ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader( mavenCli.getClass().getClassLoader() );
            try
            {
                Object result = doMain.invoke( mavenCli, new Object[] { cliArgs, workingDirectory, out, out } );

                return ( (Number) result ).intValue();
            }
            finally
            {
                Thread.currentThread().setContextClassLoader( originalClassLoader );

                System.setProperties( originalProperties );
            }
        }
        catch ( IllegalAccessException | InvocationTargetException e )
        {
            throw new LauncherException( "Failed to run Maven: " + e.getMessage(), e );
        }
        finally
        {
            if ( logFile != null )
            {
                out.close();
            }
        }
    }

    public String getMavenVersion()
        throws LauncherException
    {
        Properties props = new Properties();

        InputStream is =
            mavenCli.getClass().getResourceAsStream( "/META-INF/maven/org.apache.maven/maven-core/pom.properties" );
        if ( is != null )
        {
            try
            {
                props.load( is );
            }
            catch ( IOException e )
            {
                throw new LauncherException( "Failed to read Maven version", e );
            }
            finally
            {
                IOUtil.close( is );
            }
        }

        String version = props.getProperty( "version" );
        if ( version != null )
        {
            return version;
        }

        throw new LauncherException( "Could not determine embedded Maven version" );
    }

}
