/* ==========================================================================
 * Copyright 2003-2004 Mevenide Team
 *
 * 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.
 * =========================================================================
 */
package org.apache.netbeans.nbm.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.util.StringUtils;

/**
 * Tag examines the manifest of a jar file and retrieves NetBeans specific information.
 * @author <a href="mailto:mkleint@codehaus.org">Milos Kleint</a>
 *
 */
public class ExamineManifest
{

    private final Log logger;
    private File jarFile;
    private File manifestFile;
    private boolean netBeansModule;
    private boolean osgiBundle;

    private boolean localized;
    private String specVersion;
    private String implVersion;
    private String module;
    private String locBundle;
    private String classpath;
    private boolean publicPackages;
    private boolean populateDependencies = false;
    private List<String> dependencyTokens = Collections.<String>emptyList();
    private Set<String> osgiImports = Collections.<String>emptySet();
    private Set<String> osgiExports = Collections.<String>emptySet();

    private boolean friendPackages = false;
    private List<String> friends = Collections.<String>emptyList();
    private List<String> packages = Collections.<String>emptyList();

    private List<String> requires = Collections.<String>emptyList();

    private List<String> provides = Collections.<String>emptyList();
    //that's the default behaviour without the special manifest entry
    private boolean bundleAutoload = true;

    public ExamineManifest( Log logger )
    {
        this.logger = logger;
    }

    public void checkFile()
        throws MojoExecutionException
    {

        resetExamination();

        Manifest mf = null;
        if ( jarFile != null )
        {
            JarFile jar = null;
            try
            {
                jar = new JarFile( jarFile );
                mf = jar.getManifest();
            }
            catch ( Exception exc )
            {
                throw new MojoExecutionException( "Could not open " + jarFile + ": " + exc.getMessage(), exc );
            }
            finally
            {
                if ( jar != null )
                {
                    try
                    {
                        jar.close();
                    }
                    catch ( IOException io )
                    {
                        throw new MojoExecutionException( io.getMessage(), io );
                    }
                }
            }
        }
        else if ( manifestFile != null )
        {
            InputStream stream = null;
            try
            {
                stream = new FileInputStream( manifestFile );
                mf = new Manifest( stream );
            }
            catch ( Exception exc )
            {
                throw new MojoExecutionException( exc.getMessage(), exc );
            }
            finally
            {
                if ( stream != null )
                {
                    try
                    {
                        stream.close();
                    }
                    catch ( IOException io )
                    {
                        throw new MojoExecutionException( io.getMessage(), io );
                    }
                }
            }
        }
        if ( mf != null )
        {
            processManifest( mf );
        }
        else
        {
            //MNBMODULE-22
            File source = manifestFile;
            if ( source == null )
            {
                source = jarFile;
            }
            if ( source == null )
            {
                logger.debug( "No manifest to examine" );
            }
            else
            {
                logger.debug( "Cannot find manifest entries in " + source.getAbsolutePath() );
            }
        }
    }

    private void resetExamination()
    {
        setNetBeansModule( false );
        this.localized = false;
        this.specVersion = null;
        this.implVersion = null;
        this.module = null;
        this.locBundle = null;
        this.publicPackages = false;
        classpath = "";
    }

    private void processManifest( Manifest mf )
    {
        Attributes attrs = mf.getMainAttributes();
        this.module = attrs.getValue( "OpenIDE-Module" );
        setNetBeansModule( getModule() != null );
        if ( isNetBeansModule() )
        {
            this.locBundle = attrs.getValue( "OpenIDE-Module-Localizing-Bundle" );
            this.localized = locBundle != null;
            this.specVersion = attrs.getValue( "OpenIDE-Module-Specification-Version" );
            this.implVersion = attrs.getValue( "OpenIDE-Module-Implementation-Version" );
            String cp = attrs.getValue( Attributes.Name.CLASS_PATH );
            classpath = cp == null ? "" : cp;
            String value = attrs.getValue( "OpenIDE-Module-Public-Packages" );
            String frList = attrs.getValue( "OpenIDE-Module-Friends" );
            if ( value == null || value.trim().equals( "-" ) )
            {
                this.publicPackages = false;
            }
            else
            {
                if ( frList != null )
                {
                    this.publicPackages = false;
                    String[] friendList = StringUtils.stripAll( StringUtils.split( frList, "," ) );
                    friendPackages = true;
                    friends = Arrays.asList( friendList );
                }
                else
                {
                    this.publicPackages = true;
                }
                String[] packageList = StringUtils.stripAll( StringUtils.split( value, "," ) );
                packages = Arrays.asList( packageList );
            }
            if ( populateDependencies )
            {
                String deps = attrs.getValue( "OpenIDE-Module-Module-Dependencies" );
                if ( deps != null )
                {
                    StringTokenizer tokens = new StringTokenizer( deps, "," );
                    List<String> depList = new ArrayList<String>();
                    while ( tokens.hasMoreTokens() )
                    {
                        String tok = tokens.nextToken();
                        //we are just interested in specification and loose dependencies.
                        int spec = tok.indexOf( '>' );
                        int impl = tok.indexOf( '=');
                        if ( spec > 0 )
                        {
                            tok = tok.substring( 0, spec );
                        }
                        else if ( impl > 0 )
                        {
                            tok = tok.substring( 0, impl );
                        }
                        int slash = tok.indexOf( '/' );
                        if ( slash > 0 )
                        {
                            tok = tok.substring( 0, slash );
                        }
                        depList.add( tok.trim().intern() );
                    }
                    this.dependencyTokens = depList;
                }
                String req = attrs.getValue( "OpenIDE-Module-Requires" );
                String prov = attrs.getValue( "OpenIDE-Module-Provides" );
                String needs = attrs.getValue( "OpenIDE-Module-Needs" );
                if (prov != null) {
                    provides = Arrays.asList( StringUtils.stripAll( StringUtils.split( prov, "," ) ));
                }
                if (req != null || needs != null) {
                    requires = new ArrayList<String>();
                    if (req != null) {
                        requires.addAll(Arrays.asList( StringUtils.stripAll( StringUtils.split( req, "," ) )));
                    }
                    if (needs != null) {
                        requires.addAll(Arrays.asList( StringUtils.stripAll( StringUtils.split( needs, "," ) )));
                    }
                }
            }

        }
        else
        {
        
            //check osgi headers first, let nb stuff override it, making nb default
            String bndName = attrs.getValue( "Bundle-SymbolicName" );
            if ( bndName != null )
            {
                this.osgiBundle = true;
                this.module =
                    bndName./* MNBMODULE-125 */replaceFirst( " *;.+", "" )./* MNBMODULE-96 */replace( '-', '_' );
                this.specVersion = attrs.getValue( "Bundle-Version" );
                String exp = attrs.getValue( "Export-Package" );
                String autoload = attrs.getValue( "Nbm-Maven-Plugin-Autoload");
                if (autoload != null) {
                    bundleAutoload = Boolean.parseBoolean( autoload );
                }
                this.publicPackages = exp != null;
                if ( populateDependencies )
                {
                    //well, this doesn't appear to cover the major way of declation dependencies in osgi - Import-Package
                    String deps = attrs.getValue( "Require-Bundle" );
                    if ( deps != null )
                    {
                        List<String> depList = new ArrayList<String>();
                        // http://stackoverflow.com/questions/1757065/java-splitting-a-comma-separated-string-but-ignoring-commas-in-quotes
                        for ( String piece : deps.split( ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)" ) )
                        {
                            depList.add( piece.replaceFirst( ";.+", "" ).trim().intern() );
                        }
                        this.dependencyTokens = depList;
                    }
                    String imps = attrs.getValue( "Import-Package" );
                    if ( imps != null )
                    {
                        Set<String> depList = new HashSet<String>();
                        // http://stackoverflow.com/questions/1757065/java-splitting-a-comma-separated-string-but-ignoring-commas-in-quotes
                        for ( String piece : imps.split( ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)" ) )
                        {
                            depList.add( piece.replaceFirst( ";.+", "" ).trim().intern() );
                        }
                        this.osgiImports = depList;
                    }
                    String exps = attrs.getValue( "Export-Package" );
                    if ( exps != null )
                    {
                        Set<String> depList = new HashSet<String>();
                        // http://stackoverflow.com/questions/1757065/java-splitting-a-comma-separated-string-but-ignoring-commas-in-quotes
                        for ( String piece : exps.split( ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)" ) )
                        {
                            depList.add( piece.replaceFirst( ";.+", "" ).trim().intern() );
                        }
                        this.osgiExports = depList;
                    }
                    
                }
            }
            else
            {

                // for non-netbeans, non-osgi jars.
                this.specVersion = attrs.getValue( "Specification-Version" );
                this.implVersion = attrs.getValue( "Implementation-Version" );
                this.module = attrs.getValue( "Package" );
                this.publicPackages = false;
                classpath = "";
                /*    if ( module != null )
                {
                // now we have the package to make it a module definition, add the version there..
                module = module + "/1";
                }
                 */
                if ( getModule() == null )
                {
                    // do we want to do that?
                    this.module = attrs.getValue( "Extension-Name" );
                }
            }
        }

    }

    /**
     * The jar file to examine. It is exclusive with manifestFile.
     * @param jarFileLoc jar file
     */
    public void setJarFile( File jarFileLoc )
    {
        jarFile = jarFileLoc;
    }

    /** 
     * Manifest file to be examined. It is exclusive with jarFile.
     * @param manifestFileLoc manifedt file
     */
    public void setManifestFile( File manifestFileLoc )
    {
        manifestFile = manifestFileLoc;
    }

    /**
     * Either call {@link #setJarFile} or {@link #setManifestFile} as appropriate.
     * @param artifactFileLoc a JAR or folder
     */
    public void setArtifactFile( File artifactFileLoc )
    {
        if ( artifactFileLoc.isFile() )
        {
            setJarFile( artifactFileLoc );
        }
        else if ( artifactFileLoc.isDirectory() )
        {
            File mani = new File( artifactFileLoc, "META-INF/MANIFEST.MF" );
            if ( mani.isFile() )
            {
                setManifestFile( mani );
            } // else e.g. jarprj/target/classes has no manifest, so nothing to examine
        }
        else
        {
            throw new IllegalArgumentException( artifactFileLoc.getAbsolutePath() );
        }
    }

    public String getClasspath()
    {
        return classpath;
    }

    public boolean isNetBeansModule()
    {
        return netBeansModule;
    }

    public void setNetBeansModule( boolean netBeansModule )
    {
        this.netBeansModule = netBeansModule;
    }

    public boolean isLocalized()
    {
        return localized;
    }

    public String getSpecVersion()
    {
        return specVersion;
    }

    public String getImplVersion()
    {
        return implVersion;
    }

    /**
     * Code name base of the module only.
     * Does not include any release version.
     * @return module code name base
     */
    public String getModule()
    {
        return module != null ? module.replaceFirst( "/\\d+$", "" ) : module;
    }

    /**
     * Full name of module: code name base, then optionally slash and major release version.
     * @return module full name 
     */
    public String getModuleWithRelease()
    {
        return module;
    }

    /**
     * returns true if there are defined public packages and there is no friend
     * declaration.
     * @return true if has public package
     */
    public boolean hasPublicPackages()
    {
        return publicPackages;
    }

    public void setPopulateDependencies( boolean populateDependencies )
    {
        this.populateDependencies = populateDependencies;
    }

    public List<String> getDependencyTokens()
    {
        return dependencyTokens;
    }

    /**
     * returns true if both public packages and friend list are declared.
     * @return true if has friend package
     */
    public boolean hasFriendPackages()
    {
        return friendPackages;
    }

    public List<String> getFriends()
    {
        return friends;
    }

    /**
     * list of package statements from OpenIDE-Module-Public-Packages.
     * All items end with .*
     * @return list of package
     */
    public List<String> getPackages()
    {
        return packages;
    }

    public boolean isOsgiBundle()
    {
        return osgiBundle;
    }

    public Set<String> getOsgiImports()
    {
        return osgiImports;
    }

    public Set<String> getOsgiExports()
    {
        return osgiExports;
    }
    
    public List<String> getNetBeansRequiresTokens()
    {
        return requires;
    }

    public List<String> getNetBeansProvidesTokens()
    {
        return provides;
    }

    public boolean isBundleAutoload()
    {
        return bundleAutoload;
    }

}
