/*
 * 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.core.client;

import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.core.client.impl.Impl;

/**
 * Supports core functionality that in some cases requires direct support from
 * the compiler and runtime systems such as runtime type information and
 * deferred binding.
 */
public final class GWT {
  /**
   * This interface is used to catch exceptions at the "top level" just before
   * they escape to the browser. This is used in places where the browser calls
   * into user code such as event callbacks, timers, and RPC.
   *
   * In Development Mode, the default handler prints a stack trace to the log
   * window. In Production Mode, the default handler is null and thus exceptions
   * are allowed to escape, which provides an opportunity to use a JavaScript
   * debugger.
   */
  public interface UncaughtExceptionHandler {
    void onUncaughtException(Throwable e);
  }

  /**
   * An {@link UncaughtExceptionHandler} that logs errors to
   * {@link GWT#log(String, Throwable)}. This is the default exception handler
   * in Development Mode. In Production Mode, the default exception handler is
   * <code>null</code>.
   */
  private static final class DefaultUncaughtExceptionHandler implements
      UncaughtExceptionHandler {
    @Override
    public void onUncaughtException(Throwable e) {
      log("Uncaught exception escaped", e);
    }
  }

  /**
   * This constant is used by {@link #getPermutationStrongName} when running in
   * Development Mode.
   */
  public static final String HOSTED_MODE_PERMUTATION_STRONG_NAME = "HostedMode";

  /**
   * Defaults to <code>null</code> in Production Mode and an instance of
   * {@link DefaultUncaughtExceptionHandler} in Development Mode.
   */
  private static UncaughtExceptionHandler uncaughtExceptionHandler = null;

  /**
   * Instantiates a class via deferred binding.
   *
   * <p>
   * The argument to {@link #create(Class)}&#160;<i>must</i> be a class literal
   * because the Production Mode compiler must be able to statically determine
   * the requested type at compile-time. This can be tricky because using a
   * {@link Class} variable may appear to work correctly in Development Mode.
   * </p>
   *
   * @param classLiteral a class literal specifying the base class to be
   *          instantiated
   * @return the new instance, which must be cast to the requested class
   */
  public static <T> T create(Class<?> classLiteral) {
    /*
     * In Production Mode, the compiler directly replaces calls to this method
     * with a new Object() type expression of the correct rebound type.
     */
    return com.google.gwt.core.shared.GWT.<T>createImpl(classLiteral);
  }

  public static void exportUnloadModule() {
      Impl.exportUnloadModule();
  }

  /**
   * Gets the URL prefix of the hosting page, useful for prepending to relative
   * paths of resources which may be relative to the host page. Typically, you
   * should use {@link #getModuleBaseURL()} unless you have a specific reason to
   * load a resource relative to the host page.
   *
   * @return if non-empty, the base URL is guaranteed to end with a slash
   */
  public static String getHostPageBaseURL() {
    return Impl.getHostPageBaseURL();
  }

  /**
   * Gets the URL prefix that should be prepended to URLs that point to
   * static files generated by the GWT compiler, such as files in the
   * module's public path.
   *
   * <p>
   * Normally this will be the same value as {@link #getModuleBaseURL}, but
   * may be different when a GWT app is configured to get its static resources
   * from a different server.
   * </p>
   *
   * @return if non-empty, the base URL is guaranteed to end with a slash
   */
  public static String getModuleBaseForStaticFiles() {
    return Impl.getModuleBaseURLForStaticFiles();
  }

  /**
   * Gets the URL prefix that should be prepended to URLs that
   * are intended to be module-relative, such as RPC entry points.
   *
   * <p>If the URL points to an output file of the GWT compiler (such as
   * a file in the public path), use {@link #getModuleBaseForStaticFiles()}
   * instead.</p>
   *
   * @return if non-empty, the base URL is guaranteed to end with a slash
   */
  public static String getModuleBaseURL() {
    return Impl.getModuleBaseURL();
  }

  /**
   * Gets the name of the running module.
   */
  public static String getModuleName() {
    return Impl.getModuleName();
  }

  /**
   * Returns the permutation's strong name. This can be used to distinguish
   * between different permutations of the same module. In Development Mode,
   * this method will return {@value #HOSTED_MODE_PERMUTATION_STRONG_NAME}.
   */
  public static String getPermutationStrongName() {
    if (GWT.isScript()) {
      return Impl.getPermutationStrongName();
    } else {
      return HOSTED_MODE_PERMUTATION_STRONG_NAME;
    }
  }

  /**
   * @deprecated Use {@link Object#getClass()}, {@link Class#getName()}
   */
  @Deprecated
  public static String getTypeName(Object o) {
    return (o == null) ? null : o.getClass().getName();
  }

  /**
   * Returns the currently active uncaughtExceptionHandler.
   *
   * @return the currently active handler, or null if no handler is active.
   *
   * @see #reportUncaughtException(Throwable)
   */
  public static UncaughtExceptionHandler getUncaughtExceptionHandler() {
    return uncaughtExceptionHandler;
  }

  /**
   * Reports an exception caught at the "top level" to a handler set via
   * {@link #setUncaughtExceptionHandler(UncaughtExceptionHandler)}. This is
   * used in places where the browser calls into user code such as event
   * callbacks, timers, and RPC.
   * <p>
   * If no {@code UncaughtExceptionHandler} is set, the exception is reported
   * to browser. Browsers usually log these exceptions to the JavaScript
   * console.
   */
  public static void reportUncaughtException(Throwable e) {
    Impl.reportUncaughtException(e);
  }

  /**
   * Returns the empty string when running in Production Mode, but returns a
   * unique string for each thread in Development Mode (for example, different
   * windows accessing the dev mode server will each have a unique id, and
   * hitting refresh without restarting dev mode will result in a new unique id
   * for a particular window.
   *
   * TODO(unnurg): Remove this function once Dev Mode rewriting classes are in
   * gwt-dev.
   */
  public static String getUniqueThreadId() {
    return com.google.gwt.core.shared.GWT.getUniqueThreadId();
  }

  public static String getVersion() {
    String version = com.google.gwt.core.shared.GWT.getVersion();
    if (version == null) {
      version = getVersion0();
    }
    return version;
  }

  /**
   * Returns <code>true</code> when running inside the normal GWT environment,
   * either in Development Mode or Production Mode. Returns <code>false</code>
   * if this code is running in a plain JVM. This might happen when running
   * shared code on the server, or during the bootstrap sequence of a
   * GWTTestCase test.
   */
  public static boolean isClient() {
    return com.google.gwt.core.shared.GWT.isClient();
  }

  /**
   * Returns <code>true</code> when running in production mode. Returns
   * <code>false</code> when running either in development mode, or when running
   * in a plain JVM.
   */
  public static boolean isProdMode() {
    return com.google.gwt.core.shared.GWT.isProdMode();
  }

  /**
   * Determines whether or not the running program is script or bytecode.
   */
  public static boolean isScript() {
    return com.google.gwt.core.shared.GWT.isScript();
  }

  /**
   * Logs a message to the development shell logger in Development Mode, or to
   * the console in Super Dev Mode. Calls are optimized out in Production Mode.
   */
  public static void log(String message) {
    com.google.gwt.core.shared.GWT.log(message);
  }

  /**
   * Logs a message to the development shell logger in Development Mode, or to
   * the console in Super Dev Mode. Calls are optimized out in Production Mode.
   */
  public static void log(String message, Throwable e) {
    com.google.gwt.core.shared.GWT.log(message, e);
  }

  /**
   * Emits a JavaScript "debugger" statement on the line that called this method.
   * If the user has the browser's debugger open, the debugger will stop when the
   * GWT application executes that line. There is no effect in Dev Mode or in
   * server-side code.
   */
  public static void debugger() {
  }

  /**
   * The same as {@link #runAsync(RunAsyncCallback)}, except with an extra
   * parameter to provide a name for the call. The name parameter should be
   * supplied with a class literal. If two GWT.runAsync calls  use the same
   * class literal, the codesplitter will put the corresponding code in
   * the same code fragment.
   */
  @SuppressWarnings("unused") // parameter will be used following replacement
  public static void runAsync(Class<?> name, final RunAsyncCallback callback) {
    runAsyncImpl(callback);
  }


  /**
   * Run the specified callback once the necessary code for it has been loaded.
   */
  public static void runAsync(final RunAsyncCallback callback) {
    runAsyncImpl(callback);
  }

  private static void runAsyncImpl(final RunAsyncCallback callback) {
    Scheduler.get().scheduleDeferred(new ScheduledCommand() {
      @Override public void execute() {
        callback.onSuccess();
      }
    });
  }

  /**
   * Sets a custom uncaught exception handler. See
   * {@link #getUncaughtExceptionHandler()} for details.
   *
   * @param handler the handler that should be called when an exception is
   *        about to escape to the browser, or <code>null</code> to clear the
   *        handler and allow exceptions to escape.
   */
  public static void setUncaughtExceptionHandler(
      UncaughtExceptionHandler handler) {
    uncaughtExceptionHandler = handler;
  }

  /**
   * Called via reflection in Development Mode; do not ever call this method in
   * Production Mode.
   */
  static void setBridge(GWTBridge bridge) {
    com.google.gwt.core.shared.GWT.setBridge(bridge);
    if (bridge != null) {
      setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
    }
  }

  private static native String getVersion0() /*-{
    return $gwt_version;
  }-*/;

  /**
   * If enabled via &lt;set-property name="gwt.unloadEnabled" value="true"/> invoking this method causes the module
   * to be removed from memory and all {@link com.google.gwt.core.client.impl.Disposable} instances to be
   * cleaned up. This method is not typically called by the GWT module itself, but exported so that another module
   * may call it.
   * @see com.google.gwt.core.client.GWT#exportUnloadModule()
   */
  private static void unloadModule() {
    Impl.unloadModule();
  }
}
