/*
 * 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>create(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();
  }
}
