/*
 * Copyright 2013 Google Inc.
 *
 * 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 com.google.gwt.dev.javac;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ImportReference;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;

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

/**
 * Removes unused imports from CompilationUnitDeclarations.
 *
 * Needed after running GwtIncompatibleRemover to remove imports to GwtIncompatible elements.
 */
public class UnusedImportsRemover {

  private Set<String> usedNames = new HashSet<String>();

  /**
   * Accumulate all names that can be brought in by imports.
   *
   * This is a conservative pass, i.e. it might leave some unused imports.
   */
  private class AccumulateNamesVisitor extends ASTVisitor {
    @Override
    public void endVisit(
        SingleNameReference singleNameReference,
        BlockScope scope) {
      addName(singleNameReference);
    }

    @Override
    public void endVisit(
        SingleNameReference singleNameReference,
        ClassScope scope) {
      addName(singleNameReference);
    }

    @Override
    public void endVisit(
        SingleTypeReference singleTypeReference,
        BlockScope scope) {
      addName(singleTypeReference);
    }

    @Override
    public void endVisit(
        SingleTypeReference singleTypeReference,
        ClassScope scope) {
      addName(singleTypeReference);
    }

    @Override
    public void endVisit(MessageSend messageSend, BlockScope scope) {
      if (messageSend.receiver instanceof ThisReference) {
        usedNames.add(new String(messageSend.selector));
       }
    }

    @Override
    public void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
      addName(arrayTypeReference);
    }

    @Override
    public void endVisit(ArrayTypeReference arrayTypeReference, ClassScope scope) {
      addName(arrayTypeReference);
    }

    @Override
    public void endVisit(
        ArrayQualifiedTypeReference arrayQualifiedTypeReference,
        BlockScope scope) {
      addName(arrayQualifiedTypeReference);
    }

    @Override
    public void endVisit(
        ArrayQualifiedTypeReference arrayQualifiedTypeReference,
        ClassScope scope) {
      addName(arrayQualifiedTypeReference);
    }

    @Override
    public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
        BlockScope scope) {
      addName(parameterizedQualifiedTypeReference);
    }

    @Override
    public void endVisit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
        ClassScope scope) {
      addName(parameterizedQualifiedTypeReference);
    }

    @Override
    public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference,
        BlockScope scope) {
      addName(parameterizedSingleTypeReference);
    }

    @Override
    public void endVisit(ParameterizedSingleTypeReference parameterizedSingleTypeReference,
        ClassScope scope) {
      addName(parameterizedSingleTypeReference);
    }

    @Override
    public void endVisit(
        QualifiedTypeReference qualifiedTypeReference,
        BlockScope scope) {
      addName(qualifiedTypeReference);
    }

    @Override
    public void endVisit(
        QualifiedTypeReference qualifiedTypeReference,
        ClassScope scope) {
      addName(qualifiedTypeReference);
    }

    @Override
    public void endVisit(
        QualifiedNameReference qualifiedNameReference,
        BlockScope scope) {
      addName(qualifiedNameReference);
    }

    @Override
    public void endVisit(
        QualifiedNameReference qualifiedNameReference,
        ClassScope scope) {
      addName(qualifiedNameReference);
    }

    public void addName(QualifiedNameReference reference) {
      usedNames.add(new String(reference.tokens[0]));
    }

    public void addName(QualifiedTypeReference reference) {
      usedNames.add(new String(reference.tokens[0]));
    }

    public void addName(SingleTypeReference reference) {
      usedNames.add(new String(reference.token));
    }

    public void addName(SingleNameReference reference) {
      usedNames.add(new String(reference.token));
    }
  }

  public static void exec(CompilationUnitDeclaration cud) {
    new UnusedImportsRemover().execImpl(cud);
  }

  void execImpl(CompilationUnitDeclaration cud) {
    if (cud.imports == null) {
      return;
    }

    AccumulateNamesVisitor astVisitor = new AccumulateNamesVisitor();

    if (cud.types != null) {
      for (TypeDeclaration typeDecl : cud.types) {
        typeDecl.traverse(astVisitor, cud.scope);
      }
    }

    // for some reason JDT does not traverse package annotations even if the traversal started at
    // the Compilation unit declaration. Hence we do it manually.
    if (cud.currentPackage != null && cud.currentPackage.annotations != null) {
      for (Annotation annotation : cud.currentPackage.annotations) {
        annotation.traverse(astVisitor, (BlockScope) null);
      }
    }

    List<ImportReference> newImports = new ArrayList<ImportReference>();
    for (ImportReference importRef : cud.imports) {
      String importName =
          new String(importRef.getImportName()[importRef.getImportName().length - 1]);
      if (importName.equals("*") ||
          // very hacky it seems that this is the only way
          // to notice a import static blah.Blah.*;
          importRef.trailingStarPosition > 0  ||
          usedNames.contains(importName)) {
        // Either a * or a possible reference, so keep it.
        newImports.add(importRef);
      }
    }
    if (newImports.size() != cud.imports.length) {
      cud.imports = newImports.toArray(new ImportReference[newImports.size()]);
    }
  }
}
