/*
 * 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;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.cfg.ConfigurationProperties;
import com.google.gwt.dev.javac.CompilationState;
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.thirdparty.guava.common.base.Joiner;

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

/**
 * Constructs a Java AST for testing.
 */
public class JavaAstConstructor {

  public static final MockJavaResource ASYNCFRAGMENTLOADER = new MockJavaResource(
      "com.google.gwt.core.client.impl.AsyncFragmentLoader") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.core.client.impl;",
          "import com.google.gwt.core.client.RunAsyncCallback;",
          "public class AsyncFragmentLoader {",
          "  public static void onLoad(int fragment) { }",
          "  public static void runAsync(int fragment, RunAsyncCallback callback) { }",
          "  public static AsyncFragmentLoader BROWSER_LOADER = makeBrowserLoader(1, new int[]{});",
          "  private static AsyncFragmentLoader makeBrowserLoader(int numSp, int[] initial) {",
          "    return null;",
          "  }",
          "}");
    }
  };

  public static final MockJavaResource ARRAY = new MockJavaResource("com.google.gwt.lang.Array") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public final class Array {",
          "  static <T> T newArray(int size) { return null; }",
          "  static void setCheck(Object array, int index, Object value) { }",
          "  static void initUnidimensionalArray(",
          "      Class arrayClass, JavaScriptObject castableTypeMap,",
          "      int elementTypeId, int elementTypeCategory, int length) { }",
          "  static void initMultidimensionalArray(",
          "      Class arrayClasses[], JavaScriptObject[] castableTypeMapExprs,",
          "      int[] elementTypeIds, int leafElementTypeCategory, int[] dimExprs, int count) { }",
          "  static void stampJavaTypeInfo(Class arrayClass, JavaScriptObject castableTypeMap,",
          "      int elementTypeId, int elementTypeCategory, Object array) { }",
          "  static <T> Class<T> getClassLiteralForArray() { return null; }",
          "  public static boolean isJavaArray(Object o) { return false; }",
          "  static Object ensureNotNull(Object o) { return null; }",
          "}"
      );
    }
  };

  public static final MockJavaResource CAST = new MockJavaResource("com.google.gwt.lang.Cast") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public final class Cast {",
          "  private static JavaScriptObject stringCastMap;",
          "  private static JavaScriptObject doubleCastMap;",
          "  private static JavaScriptObject booleanCastMap;",
          "  public static native String charToString(char x) /*-{ }-*/;",
          "  public static Object castTo(Object src, int dstId) { return src;}",
          "  public static Object castToAllowJso(Object src, int dstId) { return src;}",
          "  public static Object castToArray(Object src) { return src;}",
          "  public static Object castToJsoArray(Object src) { return src;}",
          "  public static Object castToJsArray(Object src) { return src;}",
          "  public static Object castToJso(Object src) { return src;}",
          "  public static Object castToString(Object src) { return src;}",
          "  public static Object castToDouble(Object src) { return src;}",
          "  public static Object castToBoolean(Object src) { return src;}",
          "  public static Object castToNative(Object src, JavaScriptObject type) { return src;}",
          "  public static Object castToUnknownNative(Object src) { return src;}",
          "  public static Object castToFunction(Object src) { return src; }",
          "  public static Object castToJsObject(Object src) { return src; }",
          "  public static Class<?> getClass(Object src) { return null; }",
          "  public static boolean hasJavaObjectVirtualDispatch(Object o) { return true; }",
          "  public static boolean instanceOf(Object src, int dstId) { return false;}",
          "  public static boolean instanceOfString(Object o) { return true; }",
          "  public static boolean instanceOfDouble(Object o) { return true; }",
          "  public static boolean instanceOfBoolean(Object o) { return true; }",
          "  public static boolean instanceOfArray(Object src) { return false;}",
          "  public static boolean instanceOfJsoArray(Object src) { return false;}",
          "  public static boolean instanceOfJsArray(Object src) { return false;}",
          "  public static boolean instanceOfAllowJso(Object src, int dst) { return false;}",
          "  public static boolean instanceOfJso(Object src) { return false;}",
          "  public static boolean instanceOfUnknownNative(Object src)  { return false;}",
          "  public static boolean instanceOfNative(Object src, JavaScriptObject type) {",
          "    return false;",
          "  }",
          "  public static boolean instanceOfFunction(Object src) { return false; }",
          "  public static boolean instanceOfJsObject(Object src) { return false; }",
          "  public static boolean isArray(Object o) { return false; }",
          "  public static boolean isJavaScriptObject(Object o) { return true; }",
          "  public static native boolean isNull(Object a) /*-{ }-*/;",
          "  public static native boolean isNotNull(Object a) /*-{ }-*/;",
          "  public static native boolean jsEquals(Object a, Object b) /*-{ }-*/;",
          "  public static native boolean jsNotEquals(Object a, Object b) /*-{ }-*/;",
          "  public static int narrow_int(double x) { return 0; }",
          "  public static byte narrow_long(double x) { return 0; }",
          "}"
      );
    }
  };

  public static final MockJavaResource CLASS = new MockJavaResource("java.lang.Class") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package java.lang;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "public final class Class<T> {",
          "  static <T> Class<T> createForArray(String packageName, String className,",
          "      String typeId, Class<?> componentType) { return new Class<T>(); }",
          "  static <T> Class<T> createForClass(String packageName, String className,",
          "      String typeId, Class<? super T> superclass) { return new Class<T>(); }",
          "  static <T> Class<T> createForEnum(String packageName, String className,",
          "      String typeId, Class<? super T> superclass, JavaScriptObject enumConstantsFunc,",
          "      JavaScriptObject enumValueOfFunc) { return new Class<T>(); }",
          "  static <T> Class<T> createForInterface(String packageName, String className) {",
          "    return new Class<T>(); }",
          "  static <T> Class<T> createForPrimitive(String className,",
          "      String jni) { return new Class<T>(); }",
          "  static boolean isClassMetadataEnabled() { return true; }",
          "  public boolean desiredAssertionStatus() { return true; }",
          "  public String getName() { return null; }",
          "}"
      );
    }
  };

  public static final MockJavaResource CLASS_LITERAL_HOLDER = new MockJavaResource(
      "com.google.gwt.lang.ClassLiteralHolder") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "final class ClassLiteralHolder {",
          "}"
      );
    }
  };

  public static final MockJavaResource COLLAPSED_PROPERTY_HOLDER =
      new MockJavaResource("com.google.gwt.lang.CollapsedPropertyHolder") {
        @Override
        public CharSequence getContent() {
          return Joiner.on("\n").join(
              "package com.google.gwt.lang; public class CollapsedPropertyHolder {",
              "  private static final int PERMUTATION_NOT_SET = 0xFFFFFFFF;",
              "  public static int permutationId = PERMUTATION_NOT_SET;",
              "}"
          );
        }
      };


  public static final MockJavaResource ENUM = new MockJavaResource("java.lang.Enum") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package java.lang;",
          "import java.io.Serializable;",
          "import com.google.gwt.core.client.JavaScriptObject;",
          "import jsinterop.annotations.JsIgnore;",
          "import jsinterop.annotations.JsType;",
          "@JsType public abstract class Enum<E extends Enum<E>> implements Serializable {",
          "  @JsIgnore public static native <T extends Enum<T>> T valueOf(Class<T> enumType,",
          "      String name) /*-{ return enumType + name; }-*/;",
          "  public static native <T extends Enum<T>> T valueOf(JavaScriptObject enumType,",
          "      String name) /*-{ return enumType + name; }-*/;",
          "  protected static native <T extends Enum<T>> JavaScriptObject createValueOfMap(",
          "      T[] enumConstants) /*-{ }-*/;",
          "  protected Enum(String name, int ordinal) { ",
          "    this.name = name;",
          "    this.ordinal = ordinal;}",
          "  private final String name;",
          "  private final int ordinal;",
          "  public final String name() { return name; }",
          "  public final int ordinal() { return ordinal; }",
          "}"
      );
    }
  };

  public static final MockJavaResource EXCEPTIONS = new MockJavaResource(
      "com.google.gwt.lang.Exceptions") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "public class Exceptions { ",
          "  static Object toJava(Object e) { return e; }",
          "  static Object toJs(Object e) { return e; }",
          "  static RuntimeException makeAssertionError() { return new RuntimeException(); }",
          "  static Throwable safeClose(AutoCloseable resource, Throwable mainException) {",
          "    return mainException;", "  }",
          "  static <T> T checkNotNull(T value) { return value; }",
          "}"
      );
    }
  };

  public static final MockJavaResource GWT = new MockJavaResource(
      "com.google.gwt.core.client.GWT") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.core.client;",
          "public final class GWT {",
          "  public static <T> T create(Class<?> classLiteral) { return null; }",
          "  public static boolean isClient() { return true; };",
          "  public static boolean isProdMode() { return true; };",
          "  public static boolean isScript() { return true; };",
          "  public static void runAsync(RunAsyncCallback callback) { }",
          "  public static void runAsync(Class<?> name, RunAsyncCallback callback) { }",
          "}"
      );
    }
  };
  public static final MockJavaResource GWT_SHARED = new MockJavaResource(
      "com.google.gwt.core.shared.GWT") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.core.shared;",
          "public final class GWT {",
          "  public static <T> T create(Class<?> classLiteral) { return null; }",
          "  public static boolean isClient() { return true; };",
          "  public static boolean isProdMode() { return true; };",
          "  public static boolean isScript() { return true; };",
          "  public static void debugger() { }",
          "}"
      );
    }
  };

  public static final MockJavaResource IMPL =
      new MockJavaResource("com.google.gwt.core.client.impl.Impl") {
        @Override
        public CharSequence getContent() {
          return Joiner.on("\n").join(
              "package com.google.gwt.core.client.impl;",
              "public class Impl {",
              "  public static Object registerEntry(){ return null;}",
              "  public static String getNameOf(String jsniIdent) { return null; }",
              "}"
          );
        }
      };

  public static final MockJavaResource RUNTIME =
      new MockJavaResource("com.google.gwt.lang.Runtime") {
        @Override
        public CharSequence getContent() {
          return Joiner.on("\n")
              .join(
                  "package com.google.gwt.lang;",
                  "public class Runtime {",
                  "  public static Object defineClass(int typeId, int superTypeId, Object map) {",
                  "    return null;",
                  "  }",
                  "  public static void provide() {}",
                  "  public static void bootstrap() {}",
                  "  public static void emptyMethod() {}",
                  "  public static void getClassPrototype() {}",
                  "  public static String toString(Object object) { return null; }",
                  "  static native void typeMarkerFn() /*-{}-*/;",
                  "}");
        }
      };

  public static final MockJavaResource LONGLIB = new MockJavaResource(
      "com.google.gwt.lang.LongLib") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "public final class LongLib {",
          "  public static String toString(long a) { return \"\";}",
          "}"
      );
    }
  };

  public static final MockJavaResource MODULE_UTILS =
      new MockJavaResource("com.google.gwt.lang.ModuleUtils") {
        @Override
        public CharSequence getContent() {
          return Joiner.on("\n").join(
              "package com.google.gwt.lang;",
              "import com.google.gwt.core.client.impl.Impl;",
              "public class ModuleUtils {",
              "  public static void gwtOnLoad() {}",
              "  public static void addInitFunctions() {}",
              "  public static void setGwtProperty() {}",
              "  public static Object registerEntry() { return Impl.registerEntry(); }",
              "}"
          );
        }
      };

  public static final MockJavaResource RUNASYNCCALLBACK = new MockJavaResource(
      "com.google.gwt.core.client.RunAsyncCallback") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.core.client;",
          "public interface RunAsyncCallback {",
          "  void onSuccess();",
          "  void onFailure(Throwable reason);",
          "}"
      );
    }
  };

  public static final MockJavaResource RUNASYNCCODE = new MockJavaResource(
      "com.google.gwt.core.client.prefetch.RunAsyncCode") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.core.client.prefetch;",
          "public class RunAsyncCode {",
          "  public static RunAsyncCode runAsyncCode(Class<?> splitPoint) {",
          "    return null;",
          "  }",
          "}"
      );
    }
  };

  public static final MockJavaResource STATS = new MockJavaResource("com.google.gwt.lang.Stats") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "public class Stats {",
          "  static boolean isStatsAvailable() { return false; };",
          "  static boolean onModuleStart(String mainClassName) { return false; }",
          "}"
      );
    }
  };

  public static final MockJavaResource UTIL = new MockJavaResource("com.google.gwt.lang.Util") {
    @Override
    public CharSequence getContent() {
      return Joiner.on("\n").join(
          "package com.google.gwt.lang;",
          "public class Util {",
          "}"
      );
    }
  };

  public static JProgram construct(TreeLogger logger, CompilationState state,
      CompilerContext compilerContext, ConfigurationProperties config,
      String... entryPoints) throws UnableToCompleteException {
    compilerContext.getOptions().setEnableAssertions(true);
    JProgram jprogram = AstConstructor.construct(logger, state, compilerContext, config);

    // Add entry methods for entry points.
    for (String entryPoint : entryPoints) {
      JDeclaredType entryType = jprogram.getFromTypeMap(entryPoint);
      for (JMethod method : entryType.getMethods()) {
        if (method.isStatic() && JProgram.isClinit(method)) {
          jprogram.addEntryMethod(method);
        }
      }
    }
    // Tree is now ready to optimize.
    return jprogram;
  }

  public static MockJavaResource[] getCompilerTypes() {
    List<MockJavaResource> result = new ArrayList<MockJavaResource>();
    Collections.addAll(result, JavaResourceBase.getStandardResources());
    // Replace the basic Class and Enum with a compiler-specific one.
    result.remove(JavaResourceBase.CLASS);
    result.remove(JavaResourceBase.ENUM);
    Collections.addAll(result, ASYNCFRAGMENTLOADER, ARRAY, CAST, CLASS, CLASS_LITERAL_HOLDER,
        COLLAPSED_PROPERTY_HOLDER, ENUM, EXCEPTIONS, GWT, GWT_SHARED, IMPL,
        RUNTIME, LONGLIB, MODULE_UTILS, RUNASYNCCALLBACK, RUNASYNCCODE,
        UTIL);
    return result.toArray(new MockJavaResource[result.size()]);
  }
}
