package org.apache.netbeans.nbm.utils;

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


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 Milos Kleint
 *
 */
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>();
                        // https://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>();
                        // https://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>();
                        // https://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;
    }

}
