/*
 * 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.jjs.ast;

import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.SourceInfo;
import com.google.gwt.dev.jjs.ast.js.JsniMethodRef;

/**
 * Java class literal expression.
 * 
 * NOTE: This class is modeled as if it were a JFieldRef to a field declared in
 * ClassLiteralHolder. That field contains the class object allocation
 * initializer.
 */
public class JClassLiteral extends JLiteral implements JAnnotationArgument {
  /**
   * Create an expression that will evaluate, at run time, to the class literal.
   * Cannot be called after optimizations begin.
   */
  static JMethodCall computeClassObjectAllocation(JProgram program,
      SourceInfo info, JType type) {
    String typeName = getTypeName(program, type);

    JMethod method = program.getIndexedMethod(type.getClassLiteralFactoryMethod());

    /*
     * Use the classForEnum() constructor even for enum subtypes to aid in
     * pruning supertype data.
     */
    boolean isEnumOrSubclass = false;
    if (type instanceof JClassType) {
      JEnumType maybeEnum = ((JClassType) type).isEnumOrSubclass();
      if (maybeEnum != null) {
        isEnumOrSubclass = true;
        method = program.getIndexedMethod(maybeEnum.getClassLiteralFactoryMethod());
      }
    }

    assert method != null;

    JMethodCall call = new JMethodCall(info, null, method);
    JStringLiteral packageName = program.getLiteralString(info,
        getPackageName(typeName));
    JStringLiteral className = program.getLiteralString(info,
        getClassName(typeName));
    call.addArgs(packageName, className);

    if (type instanceof JArrayType) {
      // There's only one seed function for all arrays
      JDeclaredType arrayType = program.getIndexedType("Array");
      call.addArg(new JNameOf(info, className.getType(), arrayType));

    } else if (type instanceof JClassType) {
      // Add the name of the seed function for concrete types
      call.addArg(new JNameOf(info, className.getType(), type));

    } else if (type instanceof JPrimitiveType) {
      // And give primitive types an illegal, though meaningful, value
      call.addArg(program.getLiteralString(info, " "
          + type.getJavahSignatureName()));
    }

    if (type instanceof JClassType) {
      /*
       * For non-array classes and enums, determine the class literal of the
       * supertype, if there is one. Arrays are excluded because they always
       * have Object as their superclass.
       */
      JClassType classType = (JClassType) type;

      JLiteral superclassLiteral;
      if (classType.getSuperClass() != null) {
        superclassLiteral = program.getLiteralClass(classType.getSuperClass());
      } else {
        superclassLiteral = program.getLiteralNull();
      }

      call.addArg(superclassLiteral);

      if (classType instanceof JEnumType) {
        JEnumType enumType = (JEnumType) classType;
        JMethod valuesMethod = null;
        JMethod valueOfMethod = null;
        for (JMethod methodIt : enumType.getMethods()) {
          if ("values".equals(methodIt.getName())) {
            if (methodIt.getParams().size() != 0) {
              continue;
            }
            valuesMethod = methodIt;
          }
          if ("valueOf".equals(methodIt.getName())) {
            if (methodIt.getParams().size() != 1) {
              continue;
            }
            valueOfMethod = methodIt;
          }
        }
        if (valuesMethod == null) {
          throw new InternalCompilerException(
              "Could not find enum values() method");
        }
        if (valueOfMethod == null) {
          throw new InternalCompilerException(
              "Could not find enum valueOf() method");
        }
        call.addArg(new JsniMethodRef(info, null, valuesMethod,
            program.getJavaScriptObject()));
        call.addArg(new JsniMethodRef(info, null, valueOfMethod,
            program.getJavaScriptObject()));
      } else if (isEnumOrSubclass) {
        // A subclass of an enum class
        call.addArg(program.getLiteralNull());
        call.addArg(program.getLiteralNull());
      }
    } else if (type instanceof JArrayType) {
      JArrayType arrayType = (JArrayType) type;
      JClassLiteral componentLiteral = program.getLiteralClass(arrayType.getElementType());
      call.addArg(componentLiteral);
    } else {
      assert (type instanceof JInterfaceType || type instanceof JPrimitiveType);
    }
    assert call.getArgs().size() == method.getParams().size() : "Argument / param mismatch "
        + call.toString() + " versus " + method.toString();
    return call;
  }

  private static String getClassName(String fullName) {
    int pos = fullName.lastIndexOf(".");
    return fullName.substring(pos + 1);
  }

  private static String getPackageName(String fullName) {
    int pos = fullName.lastIndexOf(".");
    return fullName.substring(0, pos + 1);
  }

  private static String getTypeName(JProgram program, JType type) {
    String typeName;
    if (type instanceof JArrayType) {
      typeName = type.getJsniSignatureName().replace('/', '.');
      // Mangle the class name to match hosted mode.
      if (program.isJavaScriptObject(((JArrayType) type).getLeafType())) {
        typeName = typeName.replace(";", "$;");
      }
    } else {
      typeName = type.getName();
      // Mangle the class name to match hosted mode.
      if (program.isJavaScriptObject(type)) {
        typeName += '$';
      }
    }
    return typeName;
  }

  private final JField field;
  private final JType refType;

  /**
   * This constructor is only used by {@link JProgram}.
   */
  JClassLiteral(SourceInfo sourceInfo, JType type, JField field) {
    super(sourceInfo);
    refType = type;
    this.field = field;
  }

  public JNode annotationNode() {
    return this;
  }

  /**
   * Returns the field holding my allocated object.
   */
  public JField getField() {
    return field;
  }

  public JType getRefType() {
    return refType;
  }

  public JType getType() {
    return field.getType();
  }

  public void traverse(JVisitor visitor, Context ctx) {
    if (visitor.visit(this, ctx)) {
    }
    visitor.endVisit(this, ctx);
  }
}
