/*
 * Copyright 2008 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 com.google.gwt.dev.jdt.TypeRefVisitor;

import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;

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

/**
 * Check a {@link CompilationUnitDeclaration} for references to binary types
 * outside the context of an annotation.
 */
public class BinaryTypeReferenceRestrictionsChecker {
  /**
   * Records the location from which a {@link BinaryTypeBinding} is referenced.
   */
  static class BinaryTypeReferenceSite {
    private final BinaryTypeBinding binaryTypeBinding;
    private final Expression expression;

    BinaryTypeReferenceSite(Expression expression,
        BinaryTypeBinding binaryTypeBinding) {
      this.expression = expression;
      this.binaryTypeBinding = binaryTypeBinding;
    }

    public BinaryTypeBinding getBinaryTypeBinding() {
      return binaryTypeBinding;
    }

    public Expression getExpression() {
      return expression;
    }
  }

  /**
   * Visits a {@link CompilationUnitDeclaration} and records all expressions
   * which use a {@link BinaryTypeBinding} that are not part of an annotation
   * context.
   */
  static class BinaryTypeReferenceVisitor extends TypeRefVisitor {
    private final List<BinaryTypeReferenceSite> binaryTypeReferenceSites;

    public BinaryTypeReferenceVisitor(CompilationUnitDeclaration cud,
        List<BinaryTypeReferenceSite> binaryTypeReferenceSites) {
      super(cud);
      this.binaryTypeReferenceSites = binaryTypeReferenceSites;
    }

    @Override
    public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
      // Ignore annotations
      return false;
    }

    @Override
    public boolean visit(NormalAnnotation annotation, BlockScope scope) {
      // Ignore annotations
      return false;
    }

    @Override
    public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
      // Ignore annotations
      return false;
    }

    @Override
    protected void onBinaryTypeRef(BinaryTypeBinding binding,
        CompilationUnitDeclaration unitOfReferrer, Expression expression) {
      if (expression.constant != null && expression.constant != Constant.NotAConstant) {
        // Allow compile time constants from classes provided only in binary form.
        return;
      }
      binaryTypeReferenceSites.add(new BinaryTypeReferenceSite(expression,
          binding));
    }

    @Override
    protected void onTypeRef(SourceTypeBinding referencedType,
        CompilationUnitDeclaration unitOfReferrer) {
      // do nothing
    }
  }

  /**
   * Scans a {@link CompilationUnitDeclaration} for expressions that use
   * {@link BinaryTypeBinding}s outside the context of an annotation. An error
   * is reported against the {@link CompilationUnitDeclaration} for the first
   * instance of each unique {@link BinaryTypeBinding}.
   */
  public static void check(CompilationUnitDeclaration cud) {
    List<BinaryTypeReferenceSite> binaryTypeReferenceSites = findAllBinaryTypeReferenceSites(cud);
    Set<BinaryTypeBinding> alreadySeenTypeBindings = new HashSet<BinaryTypeBinding>();

    for (BinaryTypeReferenceSite binaryTypeReferenceSite : binaryTypeReferenceSites) {
      BinaryTypeBinding binaryTypeBinding = binaryTypeReferenceSite.getBinaryTypeBinding();
      if (alreadySeenTypeBindings.contains(binaryTypeBinding)) {
        continue;
      }
      alreadySeenTypeBindings.add(binaryTypeBinding);

      String fileName = String.valueOf(binaryTypeBinding.getFileName());
      if (fileName.endsWith(".java")) {
        // This binary name is valid; it is a reference to a unit that was
        // compiled in a previous JDT run.
        continue;
      }
      String qualifiedTypeName = binaryTypeBinding.debugName();
      String error = formatBinaryTypeRefErrorMessage(qualifiedTypeName);

      // TODO(mmendez): provide extra help info?
      GWTProblem.recordError(binaryTypeReferenceSite.getExpression(), cud,
          error, null);
    }
  }

  static List<BinaryTypeReferenceSite> findAllBinaryTypeReferenceSites(
      CompilationUnitDeclaration cud) {
    List<BinaryTypeReferenceSite> binaryTypeReferenceSites = new ArrayList<BinaryTypeReferenceSite>();
    BinaryTypeReferenceVisitor binaryTypeReferenceVisitor = new BinaryTypeReferenceVisitor(
        cud, binaryTypeReferenceSites);
    cud.traverse(binaryTypeReferenceVisitor, cud.scope);
    return binaryTypeReferenceSites;
  }

  static String formatBinaryTypeRefErrorMessage(String qualifiedTypeName) {
    return "No source code is available for type " + qualifiedTypeName
        + "; did you forget to inherit a required module?";
  }

  private BinaryTypeReferenceRestrictionsChecker() {
    // Not instantiable
  }
}
