/*
 * 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 native Object maskUndefined(Object src) /*-{ }-*/;",
          "  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()]);
  }
}
