/*
 * 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.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;

import java.util.ArrayList;
import java.util.List;

/**
 * Handles the removal of GwtIncompatible annotated classes and members.
 */
public class GwtIncompatiblePreprocessor {
  /**
   * Checks whether GwtIncompatible is in the array of {@code Annotation}.
   *
   * @param annotations an (possible null) array of {@code Annotation}
   * @return {@code true} if there is an annotation of class {@code *.GwtIncompatible} in
   *         array. {@code false} otherwise.
   */
  private static boolean hasGwtIncompatibleAnnotation(Annotation[] annotations) {
    if (annotations == null) {
      return false;
    }
    for (Annotation ann : annotations) {
      String typeName = new String(ann.type.getLastToken());
      if (typeName.equals("GwtIncompatible")) {
        return true;
      }
    }
    return false;
  }

  /**
   * Process all members of a type to remove any @GwtIncompatible one.
   */
  private static void processMembers(TypeDeclaration tyDecl) {
    processTypes(tyDecl.memberTypes);
    processMethods(tyDecl);
    processFields(tyDecl);
  }

  /**
   * Remove @GwtIncompatible classes, members and recursively remove @GwtIncompatible
   * inner classes. A dummy empty stub is retained for @GwtIncompatible classes.
   */
  private static void processTypes(TypeDeclaration[] types) {
    if (types == null) {
      return;
    }
    for (TypeDeclaration tyDecl : types) {
      if (!hasGwtIncompatibleAnnotation(tyDecl.annotations)) {
        processMembers(tyDecl);
      } else {
        // Leave the empty class.
        stripAllMembers(tyDecl);
      }
    }
  }

  /**
   * Modifies the methods array of type {@code tyDecl} to remove any GwtIncompatible methods.
   */
  private static void processMethods(TypeDeclaration tyDecl) {
    if (tyDecl.methods == null) {
      return;
    }

    List<AbstractMethodDeclaration> newMethods = new ArrayList<AbstractMethodDeclaration>();
    for (AbstractMethodDeclaration methodDecl : tyDecl.methods) {
      if (!hasGwtIncompatibleAnnotation(methodDecl.annotations)) {
        newMethods.add(methodDecl);
      }
    }

    if (newMethods.size() != tyDecl.methods.length) {
      tyDecl.methods = newMethods.toArray(new AbstractMethodDeclaration[newMethods.size()]);
    }
  }

  /**
   * Modifies the fields array of type {@code tyDecl} to remove any GwtIncompatible fields.
   */
  private static void processFields(TypeDeclaration tyDecl) {
    if (tyDecl.fields == null) {
      return;
    }

    List<FieldDeclaration> newFields = new ArrayList<FieldDeclaration>();
    for (FieldDeclaration fieldDecl : tyDecl.fields) {
      if (!hasGwtIncompatibleAnnotation(fieldDecl.annotations)) {
        newFields.add(fieldDecl);
      }
    }

    if (newFields.size() != tyDecl.fields.length) {
      tyDecl.fields = newFields.toArray(new FieldDeclaration[newFields.size()]);
    }
  }

  /**
   * Process inner classes, methods and fields from all anonymous inner classes.
   *
   * <p>Anonymous inner classes are represented inside expressions. Traverse the JDT AST removing
   * anonymous inner classes in one go.
   */
  private static void processAllAnonymousInnerClasses(CompilationUnitDeclaration cud) {
    ASTVisitor visitor = new ASTVisitor() {
      // Anonymous types are represented within the AST expression that creates the it.
      @Override
      public void endVisit(QualifiedAllocationExpression qualifiedAllocationExpression,
          BlockScope scope) {
        if (qualifiedAllocationExpression.anonymousType != null) {
          processMembers(qualifiedAllocationExpression.anonymousType);
        }
      }
    };
    cud.traverse(visitor, cud.scope);
  }

  /**
   * Removes all members of a class to leave it as an empty stub.
   */
  private static void stripAllMembers(TypeDeclaration tyDecl) {
    if (TypeDeclaration.kind(tyDecl.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
      // Do not modify annotations at all.
      return;
    }
    tyDecl.superclass = null;
    tyDecl.superInterfaces = new TypeReference[0];
    tyDecl.annotations = new Annotation[0];
    tyDecl.methods = new AbstractMethodDeclaration[0];
    tyDecl.memberTypes = new TypeDeclaration[0];
    tyDecl.fields = new FieldDeclaration[0];
    if (TypeDeclaration.kind(tyDecl.modifiers) == TypeDeclaration.CLASS_DECL) {
      // Create a default constructor so that the class is proper.
      ConstructorDeclaration constructor = tyDecl.createDefaultConstructor(true, true);
      // Mark only constructor as private so that it can not be instantiated.
      constructor.modifiers = ClassFileConstants.AccPrivate;
      // Clear a bit that is used for marking the constructor as default as it makes JDT
      // assume that the constructor is public.
      constructor.bits &= ~ASTNode.IsDefaultConstructor;
      // Mark the class as final so that it can not be extended.
      tyDecl.modifiers |= ClassFileConstants.AccFinal;
      tyDecl.modifiers &= ~ClassFileConstants.AccAbstract;
    }
  }

  /**
   * Preprocess the compilation unit to remove @GwtIncompatible classes and members.
   */
  public static void preproccess(CompilationUnitDeclaration cud) {
    processTypes(cud.types);
    processAllAnonymousInnerClasses(cud);
  }
}
