package org.apache.maven.shared.jar.classes;

/*
 * 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 org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantUtf8;
import org.apache.bcel.classfile.EmptyVisitor;
import org.apache.bcel.classfile.JavaClass;
import org.apache.commons.collections4.list.SetUniqueList;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Implementation of a BCEL class visitor that analyzes a class and collects imports.
 */
public class ImportVisitor
    extends EmptyVisitor
{
    /**
     * The list of imports discovered.
     */
    private List<String> imports;

    /**
     * The Java class that is being analyzed.
     */
    private JavaClass javaClass;

    /**
     * Pattern to detect if the import is qualified and allows retrieval of the actual import name from the string via
     * the group 1.
     */
    private static final Pattern QUALIFIED_IMPORT_PATTERN = Pattern.compile( "L([a-zA-Z][a-zA-Z0-9\\.]+);" );

    /**
     * Pattern that checks whether a string is valid UTF-8. Imports that are not are ignored.
     */
    private static final Pattern VALID_UTF8_PATTERN = Pattern.compile( "^[\\(\\)\\[A-Za-z0-9;/]+$" );

    /**
     * Create an Import visitor.
     *
     * @param javaClass the javaclass to work from
     */
    public ImportVisitor( JavaClass javaClass )
    {
        this.javaClass = javaClass;

        // Create a list that is guaranteed to be unique while retaining it's list qualities (LinkedHashSet does not
        // expose the list interface even if natural ordering is retained)  
        this.imports = SetUniqueList.setUniqueList( new ArrayList<String>() );
    }

    /**
     * Get the list of discovered imports.
     *
     * @return Returns the imports.
     */
    public List<String> getImports()
    {
        return imports;
    }

    /**
     * Find any formally declared import in the Constant Pool.
     *
     * @see org.apache.bcel.classfile.EmptyVisitor#visitConstantClass(org.apache.bcel.classfile.ConstantClass)
     */
    public void visitConstantClass( ConstantClass constantClass )
    {
        String name = constantClass.getBytes( javaClass.getConstantPool() );

        // only strings with '/' character are to be considered.
        if ( name.indexOf( '/' ) == -1 )
        {
            return;
        }

        name = name.replace( '/', '.' );

        if ( name.endsWith( ".class" ) )
        {
            name = name.substring( 0, name.length() - 6 );
        }

        Matcher mat = QUALIFIED_IMPORT_PATTERN.matcher( name );
        if ( mat.find() )
        {
            this.imports.add( mat.group( 1 ) );
        }
        else
        {
            this.imports.add( name );
        }
    }

    /**
     * Find any package class Strings in the UTF8 String Pool.
     *
     * @see org.apache.bcel.classfile.EmptyVisitor#visitConstantUtf8(org.apache.bcel.classfile.ConstantUtf8)
     */
    public void visitConstantUtf8( ConstantUtf8 constantUtf8 )
    {
        String ret = constantUtf8.getBytes().trim();

        // empty strings are not class names.
        if ( ret.length() <= 0 )
        {
            return;
        }

        // Only valid characters please.
        if ( !VALID_UTF8_PATTERN.matcher( ret ).matches() )
        {
            return;
        }

        // only strings with '/' character are to be considered.
        if ( ret.indexOf( '/' ) == -1 )
        {
            return;
        }

        // Strings that start with '/' are bad too
        // Seen when Pool has regex patterns.
        if ( ret.charAt( 0 ) == '/' )
        {
            return;
        }

        // Make string more class-like.
        ret = ret.replace( '/', '.' );

        // Double ".." indicates a bad class fail-fast.
        // Seen when ConstantUTF8 Pool has regex patterns.
        if ( ret.contains( ".." ) )
        {
            return;
        }

        Matcher mat = QUALIFIED_IMPORT_PATTERN.matcher( ret );
        char prefix = ret.charAt( 0 );

        if ( prefix == '(' )
        {
            // A Method Declaration.

            // Loop for each Qualified Class found.
            while ( mat.find() )
            {
                this.imports.add( mat.group( 1 ) );
            }
        }
        else
        {
            // A Variable Declaration.
            if ( mat.find() )
            {
                // Add a UTF8 Qualified Class reference.
                this.imports.add( mat.group( 1 ) );
            }
            else
            {
                // Add a simple Class reference.
                this.imports.add( ret );
            }
        }
    }
}
