/*
 * Copyright 2009 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.asm;

import com.google.gwt.dev.asm.AnnotationVisitor;
import com.google.gwt.dev.asm.FieldVisitor;
import com.google.gwt.dev.asm.MethodVisitor;
import com.google.gwt.dev.asm.Opcodes;
import com.google.gwt.dev.asm.commons.EmptyVisitor;
import com.google.gwt.dev.util.Name;
import com.google.gwt.dev.util.StringInterner;

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

/**
 * Reads the bytecode for a class and collects data needed for building
 * TypeOracle structures.
 */
public class CollectClassData extends EmptyVisitor {

  /**
   * Type of this class.
   */
  public enum ClassType {
    /**
     * A top level class named the same as its source file.
     */
    TopLevel,

    /**
     * A non-static named class nested inside another class.
     */
    Inner {
      @Override
      public boolean hasHiddenConstructorArg() {
        return true;
      }
    },

    /**
     * A static nested class inside another class.
     */
    Nested,

    /**
     * An anonymous inner class.
     */
    Anonymous {
      @Override
      public boolean hasNoExternalName() {
        return true;
      }
    },

    /**
     * A named class defined inside a method.
     */
    Local {
      /*
       * Note that we do not return true for hasHiddenConstructorArg since Local
       * classes inside a static method will not have one and AFAICT there is no
       * way to distinguish these cases without looking up the declaring method.
       * However, since we are dropping any classes for which
       * hasNoExternalName() returns true in TypeOracleMediator.addNewUnits, it
       * doesn't matter if we leave the synthetic argument in the list.
       */

      @Override
      public boolean hasNoExternalName() {
        return true;
      }
    };

    /**
     * @return true if this class type has a hidden constructor argument
     * for the containing instance (ie, this$0).
     */
    public boolean hasHiddenConstructorArg() {
      return false;
    }

   /**
    * @return true if this class type is not visible outside a method.
    */
    public boolean hasNoExternalName() {
      return false;
    }
  }

  /**
   * Holds the descriptor and value for an Enum-valued annotation.
   */
  public static class AnnotationEnum {
    private final String desc;
    private final String value;

    /**
     * Construct the value of an Enum-valued annotation.
     * 
     * @param desc type descriptor of this enum
     * @param value actual value in this enum
     */
    public AnnotationEnum(String desc, String value) {
      this.desc = StringInterner.get().intern(desc);
      this.value = StringInterner.get().intern(value);
    }

    /**
     * @return the type descriptor of the enum type.
     */
    public String getDesc() {
      return desc;
    }

    /**
     * @return the annotation value.
     */
    public String getValue() {
      return value;
    }
  }

  private List<CollectAnnotationData> annotations = new ArrayList<CollectAnnotationData>();

  private String source = null;
  
  // internal name
  private String name;

  private String signature;

  // internal name of superclass
  private String superName;

  // internal names of interfaces
  private String[] interfaces;
  private List<CollectMethodData> methods = new ArrayList<CollectMethodData>();
  private List<CollectFieldData> fields = new ArrayList<CollectFieldData>();
  private int access;
  private String outerClass;
  private String outerMethodName;
  private String outerMethodDesc;
  private CollectClassData.ClassType classType = ClassType.TopLevel;

  /**
   * Construct a visitor that will collect data about a class.
   */
  public CollectClassData() {
  }

  /**
   * @return the access flags for this class (ie, bitwise or of Opcodes.ACC_*).
   */
  public int getAccess() {
    return access;
  }

  /**
   * @return a list of annotations on this class.
   */
  public List<CollectAnnotationData> getAnnotations() {
    return annotations;
  }

  /**
   * @return the class type.
   */
  public CollectClassData.ClassType getClassType() {
    return classType;
  }

  /**
   * @return a list of fields in this class.
   */
  public List<CollectFieldData> getFields() {
    return fields;
  }

  /**
   * @return an array of internal names of interfaces implemented by this class.
   */
  public String[] getInterfaces() {
    return interfaces;
  }

  /**
   * @return the methods
   */
  public List<CollectMethodData> getMethods() {
    return methods;
  }

  /**
   * @return the name
   */
  public String getName() {
    return name;
  }

  /**
   * @return the outerClass
   */
  public String getOuterClass() {
    return outerClass;
  }

  /**
   * @return the outerMethodDesc
   */
  public String getOuterMethodDesc() {
    return outerMethodDesc;
  }

  /**
   * @return the outerMethodName
   */
  public String getOuterMethodName() {
    return outerMethodName;
  }

  /**
   * @return the signature
   */
  public String getSignature() {
    return signature;
  }

  /**
   * @return the source
   */
  public String getSource() {
    return source;
  }

  /**
   * @return the superName
   */
  public String getSuperName() {
    return superName;
  }

  /**
   * @return true if this class has no external name (ie, is defined inside
   * a method).
   */
  public boolean hasNoExternalName() {
    return classType.hasNoExternalName();
  }

  /**
   * @return true if this class has no source name at all.
   */
  public boolean isAnonymous() {
    return classType == ClassType.Anonymous;
  }

  @Override
  public String toString() {
    return "class " + name;
  }

  /**
   * Called at the beginning of visiting the class.
   * 
   * @param version classfile version (ie, Opcodes.V1_5 etc)
   * @param access access flags (ie, bitwise or of Opcodes.ACC_*)
   * @param name internal name of this class (ie, com/google/Foo)
   * @param signature generic signature or null
   * @param superName binary name of superclass (ie, java/lang/Object)
   * @param interfaces array of binary names of implemented interfaces
   */
  @Override
  public void visit(int version, int access, String name, String signature,
      String superName, String[] interfaces) {
    this.access = access;
    assert Name.isInternalName(name);
    this.name = name;
    this.signature = signature;
    this.superName = superName;
    this.interfaces = interfaces;
  }

  @Override
  public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
    CollectAnnotationData av = new CollectAnnotationData(desc,
        visible);
    annotations.add(av);
    return av;
  }

  /**
   * Called for each field.
   * 
   * @param access access flags for field
   * @param name field name
   * @param desc type descriptor (ie, Ljava/lang/String;)
   * @param signature generic signature (null if not generic)
   * @param value initialized value if constant
   */
  @Override
  public FieldVisitor visitField(int access, String name, String desc,
      String signature, Object value) {
    if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
      // if ("this$1".equals(name) && classType == ClassType.Anonymous) {
      // // TODO(jat): !!! really nasty hack
      // classType = ClassType.Inner;
      // }
      // skip synthetic fields
      return null;
    }
    CollectFieldData fv = new CollectFieldData(access, name, desc,
        signature, value);
    fields.add(fv);
    return fv;
  }

  /**
   * Called once for every inner class of this class.
   * 
   * @param name internal name of inner class (ie, com/google/Foo$1)
   * @param outerName internal name of enclosing class (null if not a member
   *          class or anonymous)
   * @param innerName simple name of the inner class (null if anonymous)
   * @param access access flags (bitwise or of Opcodes.ACC_*) as declared in the
   *          enclosing class
   */
  @Override
  public void visitInnerClass(String name, String outerName, String innerName,
      int access) {
    // If this inner class is ourselves, merge the access flags, since
    // static, for example, only appears in the InnerClass attribute.
    if (this.name.equals(name)) {
      if (outerName != null) {
        outerClass = outerName;
      }
      // TODO(jat): should we only pull in a subset of these flags? Use only
      // these flags, or what? For now, just grab ACC_STATIC and ACC_PRIVATE
      int copyFlags = access & (Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE);
      this.access |= copyFlags;
      boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
      switch (classType) {
        case TopLevel:
          classType = isStatic ? ClassType.Nested : ClassType.Inner;
          break;
        case Anonymous:
          if (innerName != null) {
            classType = ClassType.Local;
          }
          break;
        case Inner:
          // Already marked as inner class by the synthetic this$1 field
          break;
        default:
          throw new IllegalStateException("Unexpected INNERCLASS with type of "
              + classType);
      }
    }
  }

  @Override
  public MethodVisitor visitMethod(int access, String name, String desc,
      String signature, String[] exceptions) {
    if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
      // skip synthetic methods
      return null;
    }
    CollectMethodData mv = new CollectMethodData(classType,
        access, name, desc, signature, exceptions);
    methods.add(mv);
    return mv;
  }

  @Override
  public void visitOuterClass(String owner, String name, String desc) {
    this.outerClass = owner;
    this.outerMethodName = name;
    this.outerMethodDesc = desc;
    classType = ClassType.Anonymous; // Could be Local, catch that later
  }

  /**
   * If compiled with debug, visit the source information.
   * 
   * @param source unqualified filename containing source (ie, Foo.java)
   * @param debug additional debug information (may be null)
   */
  @Override
  public void visitSource(String source, String debug) {
    this.source = source;
  }
}
