/*********************************************************************
 * Copyright (c) 2009, 2012 SpringSource, a division of VMware, Inc.
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
**********************************************************************/

package org.eclipse.virgo.ide.bundlor.jdt.core;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.virgo.bundlor.support.partialmanifest.PartialManifest;

/**
 * {@link MethodVisitor} that is based on JDT's AST
 * </p>
 * <strong>Concurrent Semantics</strong><br />
 * Not thread safe.
 *
 * @author Christian Dupuis
 * @author Glyn Normington
 */
public class ArtifactAnalyserTypeVisitor extends ASTVisitor {

    private final PartialManifest partialManifest;

    private final Set<String> referencedTypes = new HashSet<String>();

    private String typePackage;

    public ArtifactAnalyserTypeVisitor(PartialManifest model) {
        this.partialManifest = model;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(CastExpression node) {
        recordTypeBinding(node.resolveTypeBinding());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(CatchClause node) {
        recordTypeBinding(node.getException().getType().resolveBinding());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(ClassInstanceCreation node) {
        recordTypeBinding(node.resolveTypeBinding());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(FieldDeclaration node) {
        recordTypeBinding(node.getType().resolveBinding());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(ImportDeclaration node) {
        if (node.resolveBinding() != null && !node.resolveBinding().isRecovered()) {
            IBinding binding = node.resolveBinding();
            if (binding instanceof IPackageBinding) {
                this.partialManifest.recordReferencedPackage(((IPackageBinding) binding).getName());
            } else if (binding instanceof ITypeBinding) {
                recordTypeBinding((ITypeBinding) binding);
            }
        } else {
            if (!node.isOnDemand() && !node.isStatic()) {
                Name importElementName = node.getName();
                recordFullyQualifiedName(importElementName.getFullyQualifiedName());
            } else if (node.isOnDemand() && !node.isStatic()) {
                Name importElementName = node.getName();
                this.partialManifest.recordReferencedPackage(importElementName.getFullyQualifiedName());
            } else if (!node.isOnDemand() && node.isStatic()) {
                Name importElementName = node.getName();
                String fqn = importElementName.getFullyQualifiedName().substring(0, importElementName.getFullyQualifiedName().lastIndexOf('.'));
                recordFullyQualifiedName(fqn);
            }
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(InstanceofExpression node) {
        recordTypeBinding(node.getRightOperand().resolveBinding());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(MarkerAnnotation node) {
        ITypeBinding binding = node.resolveTypeBinding();
        recordTypeBinding(binding);
        this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(binding).getName());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(MethodDeclaration node) {
        IMethodBinding binding = node.resolveBinding();
        if (binding == null) {
            return true;
        }
        // return value
        if (binding.getReturnType() != null) {
            String fqn = binding.getReturnType().getQualifiedName();
            if (!"void".equals(fqn)) {
                recordTypeBinding(binding.getReturnType());
                if (!Modifier.isPrivate(node.getModifiers())) {
                    IPackageBinding packageBinding = getPackageBinding(binding.getReturnType());
                    if (packageBinding != null) {
                        this.partialManifest.recordUsesPackage(this.typePackage, packageBinding.getName());
                    }
                }
            }
        }
        // throws clause
        if (binding.getExceptionTypes() != null) {
            for (ITypeBinding exceptionBinding : binding.getExceptionTypes()) {
                recordTypeBinding(exceptionBinding);
                if (!Modifier.isPrivate(node.getModifiers())) {
                    IPackageBinding packageBinding = getPackageBinding(exceptionBinding);
                    if (packageBinding != null) {
                        this.partialManifest.recordUsesPackage(this.typePackage, packageBinding.getName());
                    }
                }
            }
        }
        // parameter
        if (binding.getParameterTypes() != null) {
            for (ITypeBinding parameterBinding : binding.getParameterTypes()) {
                recordTypeBinding(parameterBinding);
                if (!Modifier.isPrivate(node.getModifiers())) {
                    IPackageBinding packageBinding = getPackageBinding(parameterBinding);
                    if (packageBinding != null) {
                        this.partialManifest.recordUsesPackage(this.typePackage, packageBinding.getName());
                    }
                }
            }
        }

        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(MethodInvocation node) {
        IMethodBinding binding = node.resolveMethodBinding();
        if (binding != null) {
            recordTypeBinding(binding.getDeclaringClass());

            // return value
            if (binding.getReturnType() != null) {
                recordTypeBinding(binding.getReturnType());
            }
            // parameter
            if (binding.getParameterTypes() != null) {
                for (ITypeBinding parameterBinding : binding.getParameterTypes()) {
                    recordTypeBinding(parameterBinding);
                }
            }
        } else {

        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(NormalAnnotation node) {
        ITypeBinding binding = node.resolveTypeBinding();
        recordTypeBinding(binding);
        this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(binding).getName());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(QualifiedName node) {
        IBinding binding = node.resolveBinding();

        if (isValid(binding)) {
            // Record the declared type.
            recordTypeBinding(node.resolveTypeBinding());

            // Record the declaring type.
            if (binding.getKind() == IBinding.VARIABLE) {
                recordTypeBinding(((IVariableBinding) binding).getDeclaringClass());
            }
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(SimpleName node) {
        String fqn = node.getFullyQualifiedName();
        recordFullyQualifiedName(fqn);
        return true;
    }

    /**
     * It is important to record the type binding only if it is not recovered. Recovered bindings occur for invalid
     * source code and incomplete class paths.
     *
     * @param binding the binding which may be recorded
     * @return <code>true</code> if and only if the binding should be recorded
     */
    private boolean isValid(IBinding binding) {
        return binding != null && !binding.isRecovered();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(SimpleType node) {
        if (isValid(node.resolveBinding())) {
            recordTypeBinding(node.resolveBinding());
        } else {
            Name simpleName = node.getName();
            String fqn = simpleName.getFullyQualifiedName();
            recordFullyQualifiedName(fqn);
        }
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(SingleMemberAnnotation node) {
        ITypeBinding binding = node.resolveTypeBinding();
        recordTypeBinding(binding);
        this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(binding).getName());
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(TypeDeclaration node) {
        ITypeBinding binding = node.resolveBinding();
        if (binding == null) {
            return false;
        }
        String name = binding.getBinaryName();
        this.typePackage = getPackageBinding(binding).getName();

        if (!node.isLocalTypeDeclaration()) {
            this.partialManifest.recordType(name);
        }

        for (String referencedType : this.referencedTypes) {
            recordFullyQualifiedName(referencedType);
        }

        if (node.getSuperclassType() != null) {
            ITypeBinding superClassBinding = node.getSuperclassType().resolveBinding();
            recordTypeBinding(superClassBinding);
            this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(superClassBinding).getName());
        }

        for (int i = 0; i < node.superInterfaceTypes().size(); i++) {
            org.eclipse.jdt.core.dom.Type interfaceType = (org.eclipse.jdt.core.dom.Type) node.superInterfaceTypes().get(i);
            ITypeBinding interfaceBinding = interfaceType.resolveBinding();
            recordTypeBinding(interfaceBinding);
            this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(interfaceBinding).getName());
        }

        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(AnonymousClassDeclaration node) {
        ITypeBinding binding = node.resolveBinding();
        if (binding == null) {
            return false;
        }
        this.partialManifest.recordType(binding.getBinaryName());

        ITypeBinding superClassBinding = binding.getSuperclass();
        if (superClassBinding != null) {
            recordTypeBinding(superClassBinding);
            this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(superClassBinding).getName());
        }

        ITypeBinding[] interfaceBindings = binding.getInterfaces();
        if (interfaceBindings != null) {
            for (ITypeBinding interfaceBinding : interfaceBindings) {
                recordTypeBinding(interfaceBinding);
                this.partialManifest.recordUsesPackage(this.typePackage, getPackageBinding(interfaceBinding).getName());
            }
        }

        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(AnnotationTypeDeclaration node) {
        ITypeBinding binding = node.resolveBinding();
        if (binding == null) {
            return false;
        }

        String name = binding.getBinaryName();
        this.typePackage = getPackageBinding(binding).getName();

        this.partialManifest.recordType(name);
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean visit(EnumDeclaration node) {
        ITypeBinding binding = node.resolveBinding();
        if (binding == null) {
            return false;
        }

        String name = binding.getBinaryName();
        this.typePackage = getPackageBinding(binding).getName();

        this.partialManifest.recordType(name);
        return true;
    }

    private IPackageBinding getPackageBinding(ITypeBinding binding) {
        if (binding != null) {
            if (binding.isArray()) {
                return getPackageBinding(binding.getComponentType());
            } else {
                return binding.getPackage();
            }
        }
        return null;
    }

    private String recordFullyQualifiedName(String fqn) {
        if (!"void".equals(fqn)) {
            if (this.typePackage == null) {
                this.referencedTypes.add(fqn);
                return fqn;
            } else if (fqn != null && !this.typePackage.equals(getPackageName(fqn))) {
                // This is required to get FQCNs of the form
                // org.springframework.util.ReflectionUtils.MethodCallback correctly detected
                StringTokenizer segments = new StringTokenizer(fqn, ".");
                if (segments.countTokens() > 1) {
                    List<String> newSegments = new ArrayList<String>();
                    while (segments.hasMoreTokens()) {
                        String segment = segments.nextToken();
                        newSegments.add(segment);
                        if (!Character.isLowerCase(segment.charAt(0))) {
                            break;
                        }
                    }
                    fqn = StringUtils.join(newSegments, ".");
                }

                this.partialManifest.recordReferencedType(fqn);
                return fqn;
            }
        }
        return "";
    }

    private String getPackageName(String fullyQualifiedTypeName) {
        if (fullyQualifiedTypeName == null) {
            return "";
        }
        int index = fullyQualifiedTypeName.lastIndexOf('.');

        if (index > -1) {
            return fullyQualifiedTypeName.substring(0, index);
        }

        return "";
    }

    private String recordTypeBinding(ITypeBinding binding) {
        if (binding != null) {
            if (binding.isArray()) {
                return recordTypeBinding(binding.getComponentType());
            } else {
                String fqn = binding.getBinaryName();
                return recordFullyQualifiedName(fqn);
            }
        }
        return "";
    }

}
