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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.apache.maven.mae.MAEException;
import org.apache.maven.mae.boot.embed.MAEEmbedder;
import org.apache.maven.mae.boot.embed.MAEEmbedderBuilder;
import org.apache.maven.mae.conf.MAEConfiguration;
import org.apache.maven.mae.conf.MAELibrary;
import org.apache.maven.mae.conf.VersionProvider;
import org.apache.maven.mae.conf.ext.ExtensionConfiguration;
import org.apache.maven.mae.conf.ext.ExtensionConfigurationException;
import org.apache.maven.mae.conf.loader.InstanceLibraryLoader;
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.codehaus.plexus.component.repository.exception.ComponentLookupException;

/**
 * {@link MAEApplication} implementation that provides support for loading a full Maven component environment, complete
 * with {@link MAELibrary}'s, {@link ComponentSelector} and {@link InstanceRegistry}. This class supervises the assembly
 * of the environment, giving the application developer an easy way to inject the behavior he needs.
 * 
 * @author John Casey
 */
public abstract class AbstractMAEApplication
    implements MAEApplication
{

    private final List<MAELibrary> additionalLibraries = new ArrayList<MAELibrary>();

    private final InstanceRegistry instanceRegistry = new InstanceRegistry();

    private transient boolean loaded = false;

    @SuppressWarnings( { "rawtypes", "unchecked" } )
    protected AbstractMAEApplication()
    {
        withLibrary( this );
        withComponentInstance( new ComponentKey( getClass() ), this );
    }

    /**
     * Programmatically add a new {@link MAELibrary} instance, beyond those that are automatically detected via the
     * /META-INF/services/org.apache.maven.mae.conf.MAELibrary files on the classpath.
     */
    protected final AbstractMAEApplication withLibrary( final MAELibrary library )
    {
        additionalLibraries.add( library );
        return this;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.apache.maven.mae.app.MAEApplication#load()
     */
    @Override
    public MAEApplication load()
        throws MAEException
    {
        return doLoad();
    }

    /**
     * Carry out the application loading process. This means: <br/>
     * <ul>
     * <li>Create a new {@link MAEEmbedderBuilder}</li>
     * <li>Add to that an {@link InstanceLibraryLoader} to handle libraries that were programmatically added here</li>
     * <li>Call {@link AbstractMAEApplication#beforeLoading()}</li>
     * <li>Call {@link AbstractMAEApplication#configureBuilder(MAEEmbedderBuilder)} to allow fine-tuning of the
     * {@link MAEEmbedderBuilder} instance</li>
     * <li>Call {@link MAEEmbedderBuilder#build} to create an instance of {@link MAEEmbedder}</li>
     * <li>For each instance in the {@link InstanceRegistry}, lookup via {@link MAEEmbedder#container()} to ensure
     * injectable component dependencies are filled</li>
     * <li>Call {@link AbstractMAEApplication#afterLoading()}</li>
     * <li>Set the loaded flag, which will prevent this process from repeating for an application that has already been
     * loaded</li>
     * </ul>
     */
    private synchronized final MAEApplication doLoad()
        throws MAEException
    {
        if ( loaded )
        {
            return this;
        }

        final MAEEmbedderBuilder builder =
            new MAEEmbedderBuilder().withLibraryLoader( new InstanceLibraryLoader( additionalLibraries ) );

        configureBuilder( builder );

        MAEEmbedder embedder = builder.build();
        for ( final ComponentKey<?> key : getInstanceRegistry().getInstances().keySet() )
        {
            try
            {
                builder.container().lookup( key.getRoleClass(), key.getHint() );
            }
            catch ( final ComponentLookupException e )
            {
                throw new MAEException( "Forced member-injection for registered instance: %s failed. Reason: %s", e,
                                        key, e.getMessage() );
            }
        }

        afterLoading( embedder );

        loaded = true;

        return this;
    }

    /**
     * Register a new, external component instance for injection into other components, or to have components injected
     * into it.
     */
    @SuppressWarnings( { "unchecked", "rawtypes" } )
    protected final void withComponentInstance( final Object instance )
    {
        getInstanceRegistry().add( new ComponentKey( instance.getClass() ), instance );
    }

    /**
     * Register a new {@link VirtualInstance}, which allows the component environment to bind its requirements without
     * actually having access to the component instance. The instance itself will be injected into the
     * {@link VirtualInstance} later.
     */
    protected final <C> void withVirtualComponent( final Class<C> virtualClass )
    {
        getInstanceRegistry().addVirtual( new VirtualInstance<C>( virtualClass ) );
    }

    /**
     * Set the actual instance on a {@link VirtualInstance} that was registered previously.
     */
    protected final <C, T extends C> void setVirtualInstance( final Class<C> virtualKey, final T instance )
    {
        getInstanceRegistry().setVirtualInstance( virtualKey, instance );
    }

    /**
     * Register a new, external component instance to make it available for injection, or to allow other components to
     * be injected into it.
     */
    protected final <C> void withComponentInstance( final ComponentKey<C> componentKey, final C instance )
    {
        getInstanceRegistry().add( componentKey, instance );
    }

    /**
     * Register a new {@link VirtualInstance}, which allows the component environment to bind its requirements without
     * actually having access to the component instance. The instance itself will be injected into the
     * {@link VirtualInstance} later.
     */
    protected final <C> void withVirtualComponent( final ComponentKey<C> virtualKey )
    {
        getInstanceRegistry().addVirtual( virtualKey, new VirtualInstance<C>( virtualKey.getRoleClass() ) );
    }

    /**
     * Set the actual instance on a {@link VirtualInstance} that was registered previously.
     */
    protected final <C, T extends C> void setVirtualInstance( final ComponentKey<C> virtualKey, final T instance )
    {
        getInstanceRegistry().setVirtualInstance( virtualKey, instance );
    }

    /**
     * Fine-tune the {@link MAEEmbedderBuilder} instance before it is used to create the {@link MAEEmbedder} that will
     * be used to load the application components.
     */
    protected void configureBuilder( final MAEEmbedderBuilder builder )
        throws MAEException
    {
    }

    /**
     * Hook allowing application developers access to the {@link MAEEmbedder} just after the registered external
     * component instances have been injected, but before loading is considered complete.
     */
    protected void afterLoading( final MAEEmbedder embedder )
        throws MAEException
    {
    }

    @Override
    public Logger getLogger()
    {
        return Logger.getLogger( getLogHandle() );
    }

    @Override
    public ExtensionConfiguration getConfiguration()
    {
        return null;
    }

    @Override
    public ComponentSelector getComponentSelector()
    {
        return null;
    }

    @Override
    public Set<ComponentKey<?>> getExportedComponents()
    {
        return null;
    }

    @Override
    public Set<ComponentKey<?>> getManagementComponents( final Class<?> managementType )
    {
        return null;
    }

    @Override
    public Map<Class<?>, Set<ComponentKey<?>>> getManagementComponents()
    {
        return null;
    }

    @Override
    public String getLabel()
    {
        return getName();
    }

    @Override
    public String getLogHandle()
    {
        return getId();
    }

    @Override
    public void loadConfiguration( final MAEConfiguration embConfig )
        throws ExtensionConfigurationException
    {
    }

    @Override
    public final InstanceRegistry getInstanceRegistry()
    {
        return instanceRegistry;
    }

    @Override
    public String getVersion()
    {
        final VersionProvider provider = getVersionProvider();
        if ( provider == null )
        {
            throw new IllegalStateException( "Your application booter: " + getClass().getName()
                + " must implement either getVersion() or getVersionProvider()." );
        }

        return provider.getVersion();
    }

    protected VersionProvider getVersionProvider()
    {
        return null;
    }

}
