package org.apache.maven.shared.verifier;

/*
 * 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 ( ClassNotFoundException e )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
        }
        catch ( InstantiationException e )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
        }
        catch ( IllegalAccessException e )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
        }
        catch ( NoSuchMethodException e )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
        }
        catch ( InvocationTargetException e )
        {
            throw new LauncherException( "Invalid Maven home directory " + mavenHome, e );
        }
        catch ( 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 ( ClassNotFoundException e )
        {
            throw new LauncherException( e.getMessage(), e );
        }
        catch ( NoSuchMethodException e )
        {
            throw new LauncherException( e.getMessage(), e );
        }
        catch ( InstantiationException e )
        {
            throw new LauncherException( e.getMessage(), e );
        }
        catch ( IllegalAccessException 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 e )
        {
            throw new LauncherException( "Failed to run Maven: " + e.getMessage(), e );
        }
        catch ( 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" );
    }

}
