package org.apache.maven.shared.jar;

/*
 * 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.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;

/**
 * Open a JAR file to be analyzed. Note that once created, the {@link #closeQuietly()} method should be called to
 * release the associated file handle.
 * <p/>
 * Typical usage:
 * <pre>
 *  JarAnalyzer jar = new JarAnalyzer( jarFile );
 * <p/>
 *  try
 *  {
 *      // do some analysis, such as:
 *      jarClasses = jarClassAnalyzer.analyze( jar );
 *  }
 *  finally
 *  {
 *      jar.closeQuietly();
 *  }
 * <p/>
 *  // use jar.getJarData() in some way, or the data returned by the JAR analyzer. jar itself can no longer be used.
 * </pre>
 * <p/>
 * Note: that the actual data is separated from this class by design to minimise the chance of forgetting to close the
 * JAR file. The {@link org.apache.maven.shared.jar.JarData} class exposed, as well as any data returned by actual
 * analyzers that use this class, can be used safely once this class is out of scope.
 *
 * @see org.apache.maven.shared.jar.identification.JarIdentificationAnalysis#analyze(JarAnalyzer)
 * @see org.apache.maven.shared.jar.classes.JarClassesAnalysis#analyze(JarAnalyzer)
 */
public class JarAnalyzer
{
    /**
     * Pattern to filter JAR entries for class files.
     *
     * @todo why are inner classes and other potentially valid classes omitted? (It flukes it by finding everything after $)
     */
    private static final Pattern CLASS_FILTER = Pattern.compile( "[A-Za-z0-9]*\\.class$" );

    /**
     * Pattern to filter JAR entries for Maven POM files.
     */
    private static final Pattern MAVEN_POM_FILTER = Pattern.compile( "META-INF/maven/.*/pom\\.xml$" );

    /**
     * Pattern to filter JAR entries for text files that may contain a version.
     */
    private static final Pattern VERSION_FILTER = Pattern.compile( "[Vv][Ee][Rr][Ss][Ii][Oo][Nn]" );

    /**
     * The associated JAR file.
     */
    private final JarFile jarFile;

    /**
     * Contains information about the data collected so far.
     */
    private final JarData jarData;

    /**
     * Constructor. Opens the JAR file, so should be matched by a call to {@link #closeQuietly()}.
     *
     * @param file the JAR file to open
     * @throws java.io.IOException if there is a problem opening the JAR file, or reading the manifest. The JAR file
     *             will be closed if this occurs.
     */
    public JarAnalyzer( File file )
        throws IOException
    {
        try
        {
            this.jarFile = new JarFile( file );
        }
        catch ( ZipException e )
        {
            ZipException ioe = new ZipException( "Failed to open file " + file + " : " + e.getMessage() );
            ioe.initCause( e );
            throw ioe;
        }

        // Obtain entries list.
        List<JarEntry> entries = Collections.list( jarFile.entries() );

        // Sorting of list is done by name to ensure a bytecode hash is always consistent.
        entries.sort( Comparator.comparing( ZipEntry::getName ) );

        Manifest manifest;
        try
        {
            manifest = jarFile.getManifest();
        }
        catch ( IOException e )
        {
            closeQuietly();
            throw e;
        }
        this.jarData = new JarData( file, manifest, entries );
    }

    /**
     * Get the data for an individual entry in the JAR. The caller should closeQuietly the input stream, and should not
     * retain the stream as the JAR file may be closed elsewhere.
     *
     * @param entry the JAR entry to read from
     * @return the input stream of the individual JAR entry.
     * @throws java.io.IOException if there is a problem opening the individual entry
     */
    public InputStream getEntryInputStream( JarEntry entry )
        throws IOException
    {
        return jarFile.getInputStream( entry );
    }

    /**
     * Close the associated JAR file, ignoring any errors that may occur.
     */
    public void closeQuietly()
    {
        try
        {
            jarFile.close();
        }
        catch ( IOException e )
        {
            // not much we can do about it but ignore it
        }
    }

    /**
     * Filter a list of JAR entries against the pattern.
     *
     * @param pattern the pattern to filter against
     * @return the list of files found, in {@link java.util.jar.JarEntry} elements
     */
    public List<JarEntry> filterEntries( Pattern pattern )
    {
        List<JarEntry> ret = new ArrayList<>();

        for ( JarEntry entry : getEntries() )
        {
            Matcher mat = pattern.matcher( entry.getName() );
            if ( mat.find() )
            {
                ret.add( entry );
            }
        }
        return ret;
    }

    /**
     * Get all the classes in the JAR.
     *
     * @return the list of files found, in {@link java.util.jar.JarEntry} elements
     */
    public List<JarEntry> getClassEntries()
    {
        return filterEntries( CLASS_FILTER );
    }

    /**
     * Get all the Maven POM entries in the JAR.
     *
     * @return the list of files found, in {@link java.util.jar.JarEntry} elements
     */
    public List<JarEntry> getMavenPomEntries()
    {
        return filterEntries( MAVEN_POM_FILTER );
    }

    /**
     * Get all the version text files in the JAR.
     *
     * @return the list of files found, in {@link java.util.jar.JarEntry} elements
     */
    public List<JarEntry> getVersionEntries()
    {
        return filterEntries( VERSION_FILTER );
    }

    /**
     * Get all the contained files in the JAR.
     *
     * @return the list of files found, in {@link java.util.jar.JarEntry} elements
     */
    public List<JarEntry> getEntries()
    {
        return jarData.getEntries();
    }

    /**
     * Get the file that was opened by this analyzer.
     *
     * @return the JAR file reference
     */
    public File getFile()
    {
        return jarData.getFile();
    }

    public JarData getJarData()
    {
        return jarData;
    }
}
