/*
 * 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.
 */

package org.apache.maven.mae.boot.embed;

import static org.apache.maven.mae.conf.MAELibraries.loadLibraries;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Level;
import org.apache.maven.Maven;
import org.apache.maven.cli.MavenLoggerManager;
import org.apache.maven.cli.PrintStreamLogger;
import org.apache.maven.execution.MavenExecutionRequestPopulator;
import org.apache.maven.mae.boot.services.MAEServiceManager;
import org.apache.maven.mae.conf.CoreLibrary;
import org.apache.maven.mae.conf.MAEConfiguration;
import org.apache.maven.mae.conf.MAELibrary;
import org.apache.maven.mae.conf.loader.MAELibraryLoader;
import org.apache.maven.mae.conf.loader.ServiceLibraryLoader;
import org.apache.maven.mae.internal.container.ComponentKey;
import org.apache.maven.mae.internal.container.ComponentSelector;
import org.apache.maven.mae.internal.container.InstanceRegistry;
import org.apache.maven.mae.internal.container.VirtualInstance;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.settings.building.SettingsBuilder;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.PlexusContainerException;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.Logger;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;

import com.google.inject.Module;

public class MAEEmbedderBuilder
{

    private static final MAELibraryLoader CORE_LOADER = new MAELibraryLoader()
    {
        @Override
        public Collection<? extends MAELibrary> loadLibraries( final MAEConfiguration embConfig )
            throws IOException
        {
            return Collections.singleton( new CoreLibrary() );
        }
    };

    private boolean showErrors = false;

    private boolean quiet = false;

    private boolean debug = false;

    private boolean showVersion = false;

    private PrintStream stdout = System.out;

    private PrintStream stderr = System.err;

    private InputStream stdin = System.in;

    private Logger logger;

    private File logFile;

    private MAEConfiguration config;

    private ClassWorld classWorld;

    private ClassLoader coreClassLoader;

    private Maven maven;

    private ModelProcessor modelProcessor;

    private PlexusContainer container;

    private MavenExecutionRequestPopulator executionRequestPopulator;

    private SettingsBuilder settingsBuilder;

    private DefaultSecDispatcher securityDispatcher;

    private MAEServiceManager serviceManager;

    private transient String mavenHome;

    private transient boolean loggerAutoCreated = false;

    private MAEEmbedder embedder;

    private String[] debugLogHandles;

    private boolean modelProcessorProvided;

    private boolean mavenProvided;

    private boolean executionRequestPopulatorProvided;

    private boolean settingsBuilderProvided;

    private boolean securityDispatcherProvided;

    private boolean serviceManagerProvided;

    private boolean logHandlesConfigured;

    private boolean configProvided;

    private ContainerConfiguration containerConfiguration;

    private boolean classScanningEnabled;

    private List<MAELibraryLoader> libraryLoaders;

    private final VirtualInstance<MAEEmbedder> embedderVirtual = new VirtualInstance<MAEEmbedder>( MAEEmbedder.class );

    public synchronized MAEEmbedderBuilder withSettingsBuilder( final SettingsBuilder settingsBuilder )
    {
        this.settingsBuilder = settingsBuilder;
        settingsBuilderProvided = true;
        return this;
    }

    public synchronized SettingsBuilder settingsBuilder()
        throws MAEEmbeddingException
    {
        if ( settingsBuilder == null )
        {
            settingsBuilder = lookup( SettingsBuilder.class );
            settingsBuilderProvided = false;
        }
        return settingsBuilder;
    }

    public synchronized MAEEmbedderBuilder withSecurityDispatcher( final DefaultSecDispatcher securityDispatcher )
    {
        this.securityDispatcher = securityDispatcher;
        securityDispatcherProvided = true;
        return this;
    }

    public synchronized DefaultSecDispatcher securityDispatcher()
        throws MAEEmbeddingException
    {
        if ( securityDispatcher == null )
        {
            securityDispatcher = (DefaultSecDispatcher) lookup( SecDispatcher.class, "maven" );
            securityDispatcherProvided = false;
        }
        return securityDispatcher;
    }

    public synchronized MAEEmbedderBuilder withServiceManager( final MAEServiceManager serviceManager )
    {
        this.serviceManager = serviceManager;
        serviceManagerProvided = true;
        return this;
    }

    public synchronized MAEServiceManager serviceManager()
        throws MAEEmbeddingException
    {
        if ( serviceManager == null )
        {
            serviceManager = lookup( MAEServiceManager.class );
            serviceManagerProvided = true;
        }
        return serviceManager;
    }

    public synchronized MAEEmbedderBuilder withExecutionRequestPopulator( final MavenExecutionRequestPopulator executionRequestPopulator )
    {
        this.executionRequestPopulator = executionRequestPopulator;
        executionRequestPopulatorProvided = true;
        return this;
    }

    public synchronized MavenExecutionRequestPopulator executionRequestPopulator()
        throws MAEEmbeddingException
    {
        if ( executionRequestPopulator == null )
        {
            executionRequestPopulator = lookup( MavenExecutionRequestPopulator.class );
            executionRequestPopulatorProvided = false;
        }

        return executionRequestPopulator;
    }

    public synchronized MAEEmbedderBuilder withCoreClassLoader( final ClassLoader classLoader )
    {
        coreClassLoader = classLoader;
        return this;
    }

    public synchronized MAEEmbedderBuilder withCoreClassLoader( final ClassLoader root, final Object... constituents )
        throws MalformedURLException
    {
        if ( constituents != null && constituents.length > 0 )
        {
            final Set<URL> urls = new LinkedHashSet<URL>();
            for ( final Object object : constituents )
            {
                if ( object instanceof URL )
                {
                    urls.add( (URL) object );
                }
                else if ( object instanceof CharSequence )
                {
                    urls.add( new URL( object.toString() ) );
                }
                else if ( object instanceof File )
                {
                    urls.add( ( (File) object ).toURI().toURL() );
                }
                else
                {
                    String fname;
                    ClassLoader cloader;
                    if ( object instanceof Class<?> )
                    {
                        fname = ( (Class<?>) object ).getName();
                        cloader = ( (Class<?>) object ).getClassLoader();
                    }
                    else
                    {
                        fname = object.getClass().getName();
                        cloader = object.getClass().getClassLoader();
                    }

                    fname = "/" + fname.replace( '.', '/' ) + ".class";

                    final URL resource = cloader.getResource( fname );
                    if ( resource == null )
                    {
                        throw new IllegalStateException( "Class doesn't appear in its own classloader! ["
                            + object.getClass().getName() + "]" );
                    }

                    String path = resource.toExternalForm();
                    if ( path.startsWith( "jar:" ) )
                    {
                        path = path.substring( "jar:".length() );
                    }

                    final int idx = path.indexOf( '!' );
                    if ( idx > -1 )
                    {
                        path = path.substring( 0, idx );
                    }

                    urls.add( new URL( path ) );
                }
            }

            coreClassLoader = new URLClassLoader( urls.toArray( new URL[] {} ), root );
        }
        else
        {
            coreClassLoader = root;
        }

        return this;
    }

    public synchronized MAEEmbedderBuilder withClassWorld( final ClassWorld classWorld )
    {
        this.classWorld = classWorld;
        return this;
    }

    public synchronized ClassLoader coreClassLoader()
    {
        if ( coreClassLoader == null )
        {
            coreClassLoader = Thread.currentThread().getContextClassLoader();
        }

        return coreClassLoader;
    }

    public synchronized ClassWorld classWorld()
    {
        if ( classWorld == null )
        {
            classWorld = new ClassWorld( "plexus.core", coreClassLoader() );
        }

        return classWorld;
    }

    public synchronized MAEEmbedderBuilder withContainerConfiguration( final ContainerConfiguration containerConfiguration )
    {
        this.containerConfiguration = containerConfiguration;
        return this;
    }

    public synchronized ContainerConfiguration containerConfiguration()
    {
        if ( containerConfiguration == null )
        {
            containerConfiguration =
                new DefaultContainerConfiguration().setClassWorld( classWorld() ).setName( "maven" ).setClassPathScanning( classScanningEnabled ? "ON"
                                                                                                                                           : "OFF" );
        }

        return containerConfiguration;
    }

    public synchronized MAEEmbedderBuilder withClassScanningEnabled( final boolean classScanningEnabled )
    {
        this.classScanningEnabled = classScanningEnabled;
        return this;
    }

    public boolean isClassScanningEnabled()
    {
        return classScanningEnabled;
    }

    public synchronized MAEEmbedderBuilder withMaven( final Maven maven )
    {
        this.maven = maven;
        mavenProvided = true;
        return this;
    }

    public synchronized Maven maven()
        throws MAEEmbeddingException
    {
        if ( maven == null )
        {
            maven = lookup( Maven.class );
            mavenProvided = false;
        }
        return maven;
    }

    public synchronized MAEEmbedderBuilder withModelProcessor( final ModelProcessor modelProcessor )
    {
        this.modelProcessor = modelProcessor;
        modelProcessorProvided = true;
        return this;
    }

    public synchronized ModelProcessor modelProcessor()
        throws MAEEmbeddingException
    {
        if ( modelProcessor == null )
        {
            modelProcessor = lookup( ModelProcessor.class );
            modelProcessorProvided = false;
        }

        return modelProcessor;
    }

    private <T> T lookup( final Class<T> cls )
        throws MAEEmbeddingException
    {
        try
        {
            return container().lookup( cls );
        }
        catch ( final ComponentLookupException e )
        {
            throw new MAEEmbeddingException( "Failed to lookup component: %s. Reason: %s", e, cls.getName(),
                                             e.getMessage() );
        }
    }

    private <T> T lookup( final Class<T> cls, final String hint )
        throws MAEEmbeddingException
    {
        try
        {
            return container().lookup( cls, hint );
        }
        catch ( final ComponentLookupException e )
        {
            throw new MAEEmbeddingException( "Failed to lookup component: {0} with hint: {1}. Reason: {2}", e,
                                             cls.getName(), hint, e.getMessage() );
        }
    }

    public synchronized MAEEmbedderBuilder withContainer( final PlexusContainer container )
    {
        this.container = container;
        resetContainer();

        return this;
    }

    public synchronized void resetContainer()
    {
        if ( !modelProcessorProvided )
        {
            modelProcessor = null;
        }
        if ( !executionRequestPopulatorProvided )
        {
            executionRequestPopulator = null;
        }
        if ( !settingsBuilderProvided )
        {
            settingsBuilder = null;
        }
        if ( !securityDispatcherProvided )
        {
            securityDispatcher = null;
        }
        if ( !serviceManagerProvided )
        {
            serviceManager = null;
        }
        if ( !mavenProvided )
        {
            maven = null;
        }
        if ( !configProvided )
        {
            config = null;
        }
        if ( container != null )
        {
            container = null;
        }
    }

    public synchronized PlexusContainer container()
        throws MAEEmbeddingException
    {
        // Need to switch to using: org.codehaus.plexus.MutablePlexusContainer.addPlexusInjector(List<PlexusBeanModule>,
        // Module...)
        if ( container == null )
        {
            final ContainerConfiguration cc = containerConfiguration();

            final InstanceRegistry reg = new InstanceRegistry( instanceRegistry() );
            reg.addVirtual( new ComponentKey<MAEEmbedder>( MAEEmbedder.class ), embedderVirtual );

            Module[] mods = { new ComponentSelectionModule( selector() ), new InstanceModule( reg ) };

            DefaultPlexusContainer c;
            try
            {
                c = new DefaultPlexusContainer( cc, mods );
            }
            catch ( final PlexusContainerException e )
            {
                throw new MAEEmbeddingException( "Failed to initialize component container: {0}", e, e.getMessage() );
            }

            c.setLoggerManager( new MavenLoggerManager( logger ) );

            container = c;
        }

        return container;
    }

    public synchronized ComponentSelector selector()
    {
        return configuration().getComponentSelector();
    }

    public synchronized InstanceRegistry instanceRegistry()
    {
        return configuration().getInstanceRegistry();
    }

    public MAEEmbedderBuilder withConfiguration( final MAEConfiguration config )
    {
        this.config = config;
        configProvided = true;
        return this;
    }

    public synchronized MAEConfiguration configuration()
    {
        final String[] debugLogHandles = debugLogHandles();
        if ( !logHandlesConfigured && debugLogHandles != null )
        {
            for ( final String logHandle : debugLogHandles )
            {
                final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger( logHandle );
                logger.setLevel( Level.DEBUG );
            }

            logHandlesConfigured = true;
        }

        if ( config == null )
        {
            config = new MAEConfiguration();

            if ( shouldShowDebug() )
            {
                config.withDebug();
            }
            else
            {
                config.withoutDebug();
            }

            try
            {
                final List<MAELibraryLoader> loaders = libraryLoaders();
                final Collection<MAELibrary> libraries = loadLibraries( config, loaders );
                config.withLibraries( libraries );

                if ( debugLogHandles != null
                    && Arrays.binarySearch( debugLogHandles, MAEConfiguration.STANDARD_LOG_HANDLE_CORE ) > -1 )
                {
                    MAEEmbedder.showInfo( config, loaders, standardOut() );
                }
            }
            catch ( final IOException e )
            {
                logger.error( "Failed to query context classloader for component-overrides files. Reason: "
                                  + e.getMessage(), e );
            }

            configProvided = false;
        }

        return config;
    }

    public MAEEmbedderBuilder withServiceLibraryLoader( final boolean enabled )
    {
        boolean found = false;
        final Collection<? extends MAELibraryLoader> loaders = libraryLoadersInternal();
        for ( final MAELibraryLoader loader : new LinkedHashSet<MAELibraryLoader>( loaders ) )
        {
            if ( loader instanceof ServiceLibraryLoader )
            {
                found = true;
                if ( !enabled )
                {
                    loaders.remove( loader );
                }
                else
                {
                    break;
                }
            }
        }

        if ( enabled && !found )
        {
            withLibraryLoader( new ServiceLibraryLoader() );
        }

        return this;
    }

    public boolean isServiceLibraryLoaderUsed()
    {
        for ( final MAELibraryLoader loader : libraryLoadersInternal() )
        {
            if ( loader instanceof ServiceLibraryLoader )
            {
                return true;
            }
        }

        return false;
    }

    public MAEEmbedderBuilder withLibraryLoader( final MAELibraryLoader loader )
    {
        libraryLoadersInternal().add( loader );
        return this;
    }

    public MAEEmbedderBuilder withLibraryLoader( final MAELibraryLoader loader, final int offset )
    {
        final List<MAELibraryLoader> loaders = libraryLoadersInternal();
        if ( offset < 0 )
        {
            // idx is negative, so we can add to the size here to get the insert index.
            loaders.add( loaders.size() + offset, loader );
        }
        else
        {
            loaders.add( offset, loader );
        }

        return this;
    }

    private List<MAELibraryLoader> libraryLoadersInternal()
    {
        if ( libraryLoaders == null )
        {
            libraryLoaders = new ArrayList<MAELibraryLoader>( Collections.singletonList( new ServiceLibraryLoader() ) );
        }

        return libraryLoaders;
    }

    public List<MAELibraryLoader> libraryLoaders()
    {
        final List<MAELibraryLoader> loaders = libraryLoadersInternal();

        if ( !loaders.isEmpty() && CORE_LOADER != loaders.get( 0 ) )
        {
            loaders.remove( CORE_LOADER );
        }

        loaders.add( 0, CORE_LOADER );

        return loaders;
    }

    public MAEEmbedderBuilder withVersion( final boolean showVersion )
    {
        this.showVersion = showVersion;
        return this;
    }

    public boolean showVersion()
    {
        return showVersion;
    }

    public MAEEmbedderBuilder withLogFile( final File logFile )
    {
        this.logFile = logFile;
        return this;
    }

    public File logFile()
    {
        return logFile;
    }

    public MAEEmbedderBuilder withQuietMode( final boolean quiet )
    {
        this.quiet = quiet;
        return this;
    }

    public boolean shouldBeQuiet()
    {
        return quiet;
    }

    public MAEEmbedderBuilder withDebugMode( final boolean debug )
    {
        this.debug = debug;
        return this;
    }

    public boolean shouldShowDebug()
    {
        return debug;
    }

    public MAEEmbedderBuilder withErrorMode( final boolean showErrors )
    {
        this.showErrors = showErrors;
        return this;
    }

    public boolean shouldShowErrors()
    {
        return showErrors;
    }

    public synchronized MAEEmbedderBuilder withStandardOut( final PrintStream stdout )
    {
        this.stdout = stdout;

        if ( loggerAutoCreated )
        {
            logger = null;
        }

        return this;
    }

    public PrintStream standardOut()
    {
        return stdout;
    }

    public MAEEmbedderBuilder withStandardErr( final PrintStream stderr )
    {
        this.stderr = stderr;
        return this;
    }

    public PrintStream standardErr()
    {
        return stderr;
    }

    public MAEEmbedderBuilder withStandardIn( final InputStream stdin )
    {
        this.stdin = stdin;
        return this;
    }

    public InputStream standardIn()
    {
        return stdin;
    }

    public MAEEmbedderBuilder withLogger( final Logger logger )
    {
        this.logger = logger;
        return this;
    }

    public synchronized Logger logger()
    {
        if ( logger == null )
        {
            logger = new PrintStreamLogger( stdout );
            loggerAutoCreated = true;
        }

        return logger;
    }

    public synchronized String mavenHome()
    {
        if ( mavenHome == null )
        {
            String mavenHome = System.getProperty( "maven.home" );

            if ( mavenHome != null )
            {
                try
                {
                    mavenHome = new File( mavenHome ).getCanonicalPath();
                }
                catch ( final IOException e )
                {
                    mavenHome = new File( mavenHome ).getAbsolutePath();
                }

                System.setProperty( "maven.home", mavenHome );
                this.mavenHome = mavenHome;
            }
        }

        return mavenHome;
    }

    protected synchronized void wireLogging()
    {
        if ( logFile() != null )
        {
            try
            {
                final PrintStream newOut = new PrintStream( logFile );
                withStandardOut( newOut );
            }
            catch ( final FileNotFoundException e )
            {
            }
        }

        logger();
    }

    protected synchronized MAEEmbedder createEmbedder()
        throws MAEEmbeddingException
    {
        final MAEEmbedder embedder =
            new MAEEmbedder( maven(), configuration(), container(), settingsBuilder(), executionRequestPopulator(),
                             securityDispatcher(), serviceManager(), libraryLoaders(), standardOut(), logger(),
                             shouldShowErrors(), showVersion() );

        embedderVirtual.setInstance( embedder );

        return embedder;
    }

    public synchronized MAEEmbedder build()
        throws MAEEmbeddingException
    {
        if ( embedder == null )
        {
            logger();
            configuration();
            mavenHome();

            wireLogging();
            embedder = createEmbedder();
        }

        return embedder;
    }

    public MAEEmbedderBuilder withDebugLogHandles( final String[] debugLogHandles )
    {
        this.debugLogHandles = debugLogHandles;
        logHandlesConfigured = false;

        return this;
    }

    public String[] debugLogHandles()
    {
        return debugLogHandles;
    }

}
