package org.apache.maven.artifact;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed 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.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.jelly.JellyContext;
import org.apache.maven.MavenException;
import org.apache.maven.MavenUtils;
import org.apache.maven.jelly.MavenJellyContext;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.project.Project;
import org.codehaus.plexus.util.IOUtil;

/**
 * Rewrite a full model for publishing. Inheritence and expression will have been resolved.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @version $Id$
 */
public class PomRewriter
{
    public static File getRewrittenPom( Project project )
        throws MavenException
    {
        Model model = getRewrittenModel( project.getFile(), project.getContext() );

        FileWriter w = null;
        try
        {
            MavenXpp3Writer writer = new MavenXpp3Writer();
            File f = File.createTempFile( "maven-artifact-plugin.", null );
            f.deleteOnExit();
            w = new FileWriter( f );
            writer.write( w, model );

            return f;
        }
        catch ( IOException e )
        {
            throw new MavenException( "Error getting the project as a string", e );
        }
        finally
        {
            IOUtil.close( w );
        }
    }

    static Model getRewrittenModel( File file, JellyContext context )
        throws MavenException
    {
        Model model;
        try
        {
            // Very gross, but we don't want initialize() called
            // A future version should use use project.getModel() and serialize that
            Method m = MavenUtils.class.getDeclaredMethod( "getNonJellyProject", new Class[]{File.class,
                                                                                             MavenJellyContext.class,
                                                                                             boolean.class} );
            m.setAccessible( true );
            Project p = (Project) m.invoke( null, new Object[]{file, context, Boolean.TRUE} );
            m.setAccessible( false );
            m = MavenUtils.class.getDeclaredMethod( "getJellyProject", new Class[]{Project.class} );
            m.setAccessible( true );
            p = (Project) m.invoke( null, new Object[]{p} );
            m.setAccessible( false );
            // The rewrittenPOM must redefine dependencies versions
            // if override properties are used
            p.buildArtifactList();
            
            // now sanitize
            p.setContext( null );
            p.setParent( null );
            p.setArtifacts( null );
            p.setDependencyVerifier( null );
            p.setExtend( null );

            Map depProperties = new HashMap();
            for ( Iterator i = p.getDependencies().iterator(); i.hasNext(); )
            {
                org.apache.maven.project.Dependency d = (org.apache.maven.project.Dependency) i.next();
                Map properties = d.getProperties();
                if ( properties != null && !properties.isEmpty() )
                {
                    depProperties.put( d.getId(), properties );
                    d.setProperties( null );
                }
            }

            String asString = p.getProjectAsString();

            MavenXpp3Reader reader = new MavenXpp3Reader();
            model = reader.read( new StringReader( asString ) );
            model.setId( null );

            for ( Iterator i = model.getDependencies().iterator(); i.hasNext(); )
            {
                Dependency d = (Dependency) i.next();

                if ( depProperties.containsKey( d.getId() ) )
                {
                    d.getProperties().putAll( (Map) depProperties.get( d.getId() ) );
                }

                d.setId( null );

                if ( d.getUrl() != null && d.getUrl().length() == 0 )
                {
                    d.setUrl( null );
                }

                if ( d.getType() != null && d.getType().length() == 0 )
                {
                    d.setType( null );
                }

                if ( d.getJar() != null && d.getJar().length() == 0 )
                {
                    d.setJar( null );
                }

            }
        }
        catch ( Exception e )
        {
            throw new MavenException( "Error getting the project as a string", e );
        }
        return model;
    }
}
