/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included with this distribution in
 * the LICENSE file.
 */
package org.apache.myrmidon.components.builder;

import java.net.URL;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.avalon.framework.ExceptionUtil;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.log.Logger;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.framework.Condition;
import org.apache.myrmidon.components.model.DefaultProject;
import org.apache.myrmidon.components.model.TypeLib;
import org.apache.myrmidon.components.model.Project;
import org.apache.myrmidon.components.model.Target;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 * Default implementation to construct project from a build file.
 *
 * @author <a href="mailto:donaldp@apache.org">Peter Donald</a>
 */
public class DefaultProjectBuilder
    extends AbstractLoggable
    implements ProjectBuilder
{
    private final static int    PROJECT_REFERENCES  = 0;
    private final static int    LIBRARY_IMPORTS     = 1;
    private final static int    IMPLICIT_TASKS      = 2;
    private final static int    TARGETS             = 3;

    /**
     * build a project from file.
     *
     * @param source the source
     * @return the constructed Project
     * @exception IOException if an error occurs
     * @exception Exception if an error occurs
     */
    public Project build( final String source )
        throws Exception
    {
        final File file = new File( source );
        return build( file, new HashMap() );
    }

    private Project build( final File file, final HashMap projects )
        throws Exception
    {
        final URL systemID = file.toURL();
        final Project result = (Project)projects.get( systemID.toString() );
        if( null != result )
        {
            return result;
        }

        final SAXConfigurationHandler handler = new SAXConfigurationHandler();

        process( systemID, handler );

        final Configuration configuration = handler.getConfiguration();

        final DefaultProject project = buildProject( file, configuration );

        projects.put( systemID.toString(), project );

        //build using all top-level attributes
        buildTopLevelProject( project, configuration, projects );

        return project;
    }

    protected void process( final URL systemID, 
                            final SAXConfigurationHandler handler )
        throws Exception
    {
        final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        final SAXParser saxParser = saxParserFactory.newSAXParser();
        final XMLReader parser = saxParser.getXMLReader();
        parser.setFeature( "http://xml.org/sax/features/namespace-prefixes", false );
        parser.setFeature( "http://xml.org/sax/features/namespaces", false );
        //parser.setFeature( "http://xml.org/sax/features/validation", false );

        parser.setContentHandler( handler );
        parser.setErrorHandler( handler );
        parser.parse( systemID.toString() );
    }

    /**
     * build project from configuration.
     *
     * @param file the file from which configuration was loaded
     * @param configuration the configuration loaded
     * @return the created Project
     * @exception IOException if an error occurs
     * @exception Exception if an error occurs
     * @exception ConfigurationException if an error occurs
     */
    private DefaultProject buildProject( final File file,
                                         final Configuration configuration )
        throws Exception
    {
        if( !configuration.getName().equals( "project" ) )
        {
            throw new Exception( "Project file must be enclosed in project element" );
        }

        //get project-level attributes
        final String baseDirectoryName = configuration.getAttribute( "basedir" );
        final String defaultTarget = configuration.getAttribute( "default" );
        //final String name = configuration.getAttribute( "name" );

        //determine base directory for project
        final File baseDirectory =
            (new File( file.getParentFile(), baseDirectoryName )).getAbsoluteFile();

        getLogger().debug( "Project " + file + " base directory: " + baseDirectory );

        //create project and ...
        final DefaultProject project = new DefaultProject();
        project.setDefaultTargetName( defaultTarget );
        project.setBaseDirectory( baseDirectory );
        //project.setName( name );

        return project;
    }

    /**
     * Handle all top level elements in configuration.
     *
     * @param project the project
     * @param configuration the Configuration
     * @exception Exception if an error occurs
     */
    private void buildTopLevelProject( final DefaultProject project, 
                                       final Configuration configuration,
                                       final HashMap projects )
        throws Exception
    {
        final ArrayList implicitTaskList = new ArrayList();
        final Configuration[] children = configuration.getChildren();

        int state = PROJECT_REFERENCES;

        for( int i = 0; i < children.length; i++ )
        {
            final Configuration element = children[ i ];
            final String name = element.getName();

            if( PROJECT_REFERENCES == state )
            {
                if( name.equals( "projectref" ) )
                {
                    buildProjectRef( project, element, projects );
                    continue;
                }
                else
                {
                    state = LIBRARY_IMPORTS;
                }
            }

            if( LIBRARY_IMPORTS == state )
            {
                if( name.equals( "import" ) )
                {
                    buildTypeLib( project, element );
                    continue;
                }
                else
                {
                    state = IMPLICIT_TASKS;
                }
            }

            if( IMPLICIT_TASKS == state )
            {
                //Check for any implicit tasks here
                if( !name.equals( "target" ) )
                {
                    implicitTaskList.add( element );
                    continue;
                }
                else
                {
                    state = TARGETS;
                }
            }

            if( name.equals( "target" ) ) buildTarget( project, element );
            else
            {
                throw new Exception( "Unknown top-level element " + name +
                                     " at " + element.getLocation() +
                                     ". Expecting target" );
            }
        }

        final Configuration[] implicitTasks =
            (Configuration[])implicitTaskList.toArray( new Configuration[ 0 ] );

        final Target implicitTarget = new Target( null, implicitTasks, null );
        project.setImplicitTarget( implicitTarget );
    }

    private void buildProjectRef( final DefaultProject project,
                                  final Configuration element,
                                  final HashMap projects )
        throws Exception
    {
        final String name = element.getAttribute( "name", null );
        final String location = element.getAttribute( "location", null );

        if( null == name )
        {
            throw new Exception( "Malformed projectref without a name attribute at " +
                                 element.getLocation() );
        }

        if( !validName( name ) )
        {
            throw new Exception( "Projectref with an invalid name attribute at " +
                                 element.getLocation() );
        }

        if( null == location )
        {
            throw new Exception( "Malformed projectref without a location attribute at " +
                                 element.getLocation() );
        }

        final File baseDirectory = project.getBaseDirectory();

        //TODO: standardize and migrate to Avalon-Excalibur.io
        final File file = new File( baseDirectory, location );

        final String systemID = file.toURL().toString();
        Project other = (Project)projects.get( systemID );

        if( null == other )
        {
            other = build( file, projects );
        }

        project.addProject( name, other );
    }

    private void buildTypeLib( final DefaultProject project,
                               final Configuration element )
        throws Exception
    {
        final String library = element.getAttribute( "library", null );
        final String name = element.getAttribute( "name", null );
        final String type = element.getAttribute( "type", null );

        if( null == library )
        {
            throw new Exception( "Malformed import without a library attribute at " +
                                 element.getLocation() );
        }

        if( null == name || null == type )
        {
            if( null != name || null != type )
            {
                throw new Exception( "Malformed import at " + element.getLocation() +
                                     ". If name or type attribute is specified, both " +
                                     "attributes must be specified." );
            }
        }

        project.addTypeLib( new TypeLib( library, type, name ) );
    }

    /**
     * Build a target from configuration.
     *
     * @param project the project
     * @param task the Configuration
     */
    private void buildTarget( final DefaultProject project, final Configuration target )
        throws Exception
    {
        final String name = target.getAttribute( "name", null );
        final String depends = target.getAttribute( "depends", null );
        final String ifCondition = target.getAttribute( "if", null );
        final String unlessCondition = target.getAttribute( "unless", null );

        if( null == name )
        {
            throw new Exception( "Discovered un-named target at " +
                                 target.getLocation() );
        }

        if( !validName( name ) )
        {
            throw new Exception( "Target with an invalid name at " +
                                 target.getLocation() );
        }

        getLogger().debug( "Parsing target: " + name );

        if( null != ifCondition && null != unlessCondition )
        {
            throw new Exception( "Discovered invalid target that has both a if and " +
                                    "unless condition at " + target.getLocation() );
        }

        Condition condition = null;

        if( null != ifCondition )
        {
            getLogger().debug( "Target if condition: " + ifCondition );
            condition = new Condition( true, ifCondition );
        }
        else if( null != unlessCondition )
        {
            getLogger().debug( "Target unless condition: " + unlessCondition );
            condition = new Condition( false, unlessCondition );
        }

        String[] dependencies = null;

        //apply depends attribute
        if( null != depends )
        {
            final String[] elements = ExceptionUtil.splitString( depends, "," );
            final ArrayList dependsList = new ArrayList();

            for( int i = 0; i < elements.length; i++ )
            {
                final String dependency = elements[ i ].trim();

                if( 0 == dependency.length() )
                {
                    throw new Exception( "Discovered empty dependency in target " +
                                         target.getName() + " at " + target.getLocation() );
                }

                getLogger().debug( "Target dependency: " + dependency );
                dependsList.add( dependency );
            }

            dependencies = (String[])dependsList.toArray( new String[ 0 ] );
        }

        final Target defaultTarget =
            new Target( condition, target.getChildren(), dependencies );

        //add target to project
        project.addTarget( name, defaultTarget );
    }

    protected boolean validName( final String name )
    {
        if( -1 != name.indexOf( "->" ) ) return false;
        else return true;
    }
}
