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

import com.google.gwt.junit.JUnitShell;
import com.google.gwt.junit.JUnitShell.Strategy;
import com.google.gwt.junit.PropertyDefiningStrategy;
import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;

import junit.framework.TestCase;
import junit.framework.TestResult;

import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

/**
 * Acts as a bridge between the JUnit environment and the GWT environment. We
 * hook the run method and stash the TestResult object for later communication
 * between the test runner and the unit test shell that drives the test case
 * inside a hosted browser.
 *
 * <p>
 * There are two versions of this class. This version is the binary version that
 * derives from JUnit's {@link TestCase} and handles all the work of starting up
 * the GWT environment. The other version is a translatable class that is used
 * within the browser. See the <code>translatable</code> subpackage for the
 * translatable implementation.
 * </p>
 */
@SuppressWarnings("unused") 
public abstract class GWTTestCase extends TestCase {

  /**
   * Information about a synthetic module used for testing.
   */
  public static final class TestModuleInfo {
    private String moduleName;
    private String syntheticModuleName;
    private Strategy strategy;

    /**
     * The ordered tests in this synthetic module.
     */
    private Set<TestInfo> tests = new LinkedHashSet<TestInfo>();

    /**
     * Construct a new {@link TestModuleInfo}.
     *
     * @param moduleName the module name
     * @param syntheticModuleName the synthetic module name
     * @param strategy the test {@link Strategy}
     */
    public TestModuleInfo(String moduleName, String syntheticModuleName,
        Strategy strategy) {
      this.moduleName = moduleName;
      this.syntheticModuleName = syntheticModuleName;
      this.strategy = strategy;
    }

    public String getModuleName() {
      return moduleName;
    }

    public Strategy getStrategy() {
      return strategy;
    }

    public String getSyntheticModuleName() {
      return syntheticModuleName;
    }

    /**
     * Returns the tests that are part of this module.
     */
    public Set<TestInfo> getTests() {
      return tests;
    }
  }

  /**
   * Records all live GWTTestCases by synthetic module name so we can optimize
   * run they are compiled and run.  Ordered so that we can precompile the
   * modules in the order that they will run.
   */
  public static final Map<String, TestModuleInfo> ALL_GWT_TESTS = new LinkedHashMap<String, TestModuleInfo>();

  /**
   * The lock for ALL_GWT_TESTS.
   */
  private static final Object ALL_GWT_TESTS_LOCK = new Object();

  /**
   * Get the names of all test modules.
   *
   * @return all test module names
   */
  public static String[] getAllTestModuleNames() {
    synchronized (ALL_GWT_TESTS_LOCK) {
      return ALL_GWT_TESTS.keySet().toArray(new String[ALL_GWT_TESTS.size()]);
    }
  }

  /**
   * Get the number of modules.
   *
   * @return the module count.
   */
  public static int getModuleCount() {
    synchronized (ALL_GWT_TESTS_LOCK) {
      return ALL_GWT_TESTS.size();
    }
  }

  /**
   * Get the set of all {@link TestInfo} for the specified module.
   *
   * @param syntheticModuleName the synthetic module name
   * @return all tests for the module
   */
  public static TestModuleInfo getTestsForModule(String syntheticModuleName) {
    synchronized (ALL_GWT_TESTS_LOCK) {
      return ALL_GWT_TESTS.get(syntheticModuleName);
    }
  }

  /**
   * Object that collects the results of this test case execution.
   */
  protected TestResult testResult = null;

  /**
   * Whether this test case should be always run in pure Java mode (non-GWT).
   * Setting this to <code>true</code> has the same effect as returning
   * <code>null</code> in {@link #getModuleName}.
   *
   * @see #isPureJava
   */
  private boolean forcePureJava;

  /**
   * The {@link Strategy} used by this test.
   */
  private Strategy strategy;

  /**
   * A new instance of your subclass is constructed for each test method that is
   * to be run. You should avoid running code in your subclass constructor,
   * initializer blocks, and field initializations, because if those code blocks
   * must be runnable outside of the GWT environment. As an example of what
   * could go wrong if you run code there, trying to run a JSNI method could
   * generate an {@link UnsatisfiedLinkError}, and trying to call
   * {@link com.google.gwt.core.client.GWT#create(Class)} could throw an
   * {@link UnsupportedOperationException}. Instead, override
   * {@link #gwtSetUp()} and perform any initialization code there.
   */
  public GWTTestCase() {
  }

  /**
   * Determines whether or not exceptions will be caught by the test fixture.
   * Override this method and return <code>false</code> to let exceptions escape
   * to the browser. This will break the normal JUnit reporting functionality,
   * but can be useful in Production Mode with a JavaScript debugger to pin down
   * where exceptions are originating.
   *
   * @return <code>true</code> for normal JUnit behavior, or <code>false</code>
   *         to disable normal JUnit exception reporting
   */
  public boolean catchExceptions() {
    return true;
  }

  /**
   * Specifies a module to use when running this test case. Subclasses must
   * return the name of a module that will cause the source for that subclass to
   * be included.
   *
   * @return the fully qualified name of a module, or <code>null</code> to run
   *         as a pure Java (non-GWT) test case (same effect as passing
   *         <code>true</code> to {@link #setForcePureJava})
   *
   * @see #isPureJava
   */
  public abstract String getModuleName();

  /**
   * Get the {@link Strategy} to use when compiling and running this test.
   *
   * @return the test {@link Strategy}
   */
  public Strategy getStrategy() {
    if (strategy == null) {
      strategy = new PropertyDefiningStrategy(this);
    }
    return strategy;
  }

  /**
   * Get the synthetic module name, which includes the synthetic extension
   * defined by the {@link Strategy}.
   *
   * @return the synthetic module name, or <code>null</code> if this test case
   *         is run in pure Java mode (non-GWT)
   *
   * @see #isPureJava
   */
  public final String getSyntheticModuleName() {
    if (isPureJava()) {
      return null;
    } else {
      return getModuleName() + "." + getStrategy().getSyntheticModuleExtension();
    }
  }

  /**
   * Returns whether this test case should be run in pure Java mode (non-GWT).
   * Returns <code>true</code> if and only if {@link #getModuleName} returns
   * <code>null</code>, or {@link #setForcePureJava} was last invoked with
   * <code>true</code>.
   */
  public boolean isPureJava() {
    return forcePureJava || (getModuleName() == null);
  }

  /**
   * Stashes <code>result</code> so that it can be accessed during
   * {@link #runTest()}.
   */
  @Override
  public final void run(TestResult result) {
    testResult = result;
    super.run(result);
  }

  /**
   * Specifies whether this test case should be always run in pure Java mode
   * (non-GWT). Passing <code>true</code> has the same effect as returning
   * <code>null</code> in {@link #getModuleName}. The setting is
   * <code>false</code> by default.
   *
   * @param forcePureJava <code>true</code> to always run this test case in pure
   *        Java mode (non-GWT); <code>false</code> to run this test case in GWT
   *        mode if {@link #getModuleName} does not return <code>null</code>
   *
   * @see #isPureJava
   */
  public void setForcePureJava(boolean forcePureJava) {
    this.forcePureJava = forcePureJava;
  }

  @Override
  public void setName(String name) {
    super.setName(name);

    synchronized (ALL_GWT_TESTS_LOCK) {
      // Once the name is set, we can add ourselves to the global set.
      String syntheticModuleName = getSyntheticModuleName();
      TestModuleInfo moduleInfo = ALL_GWT_TESTS.get(syntheticModuleName);
      if (moduleInfo == null) {
        // It should be safe to assume that tests with the same synthetic module
        // name have the same test strategy. If they didn't, they would compile
        // over each other.
        moduleInfo = new TestModuleInfo(getModuleName(), syntheticModuleName,
            getStrategy());
        ALL_GWT_TESTS.put(syntheticModuleName, moduleInfo);
      }
      moduleInfo.getTests().add(
          new TestInfo(syntheticModuleName, getClass().getName(), getName()));
    }
  }

  /**
   * Put the current test in asynchronous mode. If the test method completes
   * normally, this test will not immediately succeed. Instead, a <i>delay
   * period</i> begins. During the delay period, the test system will wait for
   * one of three things to happen:
   *
   * <ol>
   * <li> If {@link #finishTest()} is called before the delay period expires,
   * the test will succeed.</li>
   * <li> If any exception escapes from an event handler during the delay
   * period, the test will error with the thrown exception.</li>
   * <li> If the delay period expires and neither of the above has happened, the
   * test will error with a {@link TimeoutException}. </li>
   * </ol>
   *
   * <p>
   * This method is typically used to test event driven functionality.
   * </p>
   *
   * <p>
   * <b>Example:</b>
   * {@example com.google.gwt.examples.AsyncJUnitExample#testTimer()}
   * </p>
   *
   * @param timeoutMillis how long to wait before the current test will time out
   * @tip Subsequent calls to this method reset the timeout.
   * @see #finishTest()
   *
   * @throws UnsupportedOperationException if {@link #supportsAsync()} is false
   */
  protected final void delayTestFinish(int timeoutMillis) {
    // implemented in the translatable version of this class
  }

  /**
   * Cause this test to succeed during asynchronous mode. After calling
   * {@link #delayTestFinish(int)}, call this method during the delay period to
   * cause this test to succeed. This method is typically called from an event
   * handler some time after the test method returns control to the caller.
   *
   * <p>
   * Calling this method before the test method completes, will undo the effect
   * of having called <code>delayTestFinish()</code>. The test will revert to
   * normal, non-asynchronous mode.
   * </p>
   *
   * <p>
   * <b>Example:</b>
   * {@example com.google.gwt.examples.AsyncJUnitExample#testTimer()}
   * </p>
   *
   * @throws IllegalStateException if this test is not in asynchronous mode
   * @throws UnsupportedOperationException if {@link #supportsAsync()} is false
   *
   * @see #delayTestFinish(int)
   */
  protected final void finishTest() {
    // implemented in the translatable version of this class
  }

  /**
   * Reports an exception that might have escaped to the browser.
   * <p>
   * This method is called by the test framework to report uncaught exceptions. The default
   * implementation causes the test case to be reported as 'failed'. However in some rare situations
   * where an uncaught exception is expected, a test case may choose to alter the behavior by
   * overriding it:
   * <pre>
   * class SomeTestCase extends GWTTestCase {
   *
   *   class ExpectedTestException extends Exception {}
   *
   *   {@literal @}Override
   *   protected void reportUncaughtException(Throwable t) {
   *     // Ignore exceptions that are expected to be thrown by our test cases:
   *     if (t instanceof ExpectedTestException) {
   *       return;
   *     }
   *     super.reportUncaughtException(t);
   *   }
   *   ...
   * }
   * </pre>
   *
   * Note that this method will not cause the test case to fail immediately if the main test body is
   * still executing. In that case, test will fail after the main body returns with the reported
   * exception. If the test has already finished (fail or success) before this method is called,
   * the reported exception is currently ignored, but this may result in an error in a future
   * version of GWT.
   *
   * @see com.google.gwt.core.client.GWT#reportUncaughtException
   */
  protected void reportUncaughtException(Throwable ex) {
    // implemented in the translatable version of this class
  }

  /**
   * A replacement for JUnit's {@link #setUp()} method. This method runs once
   * per test method in your subclass, just before your each test method runs
   * and can be used to perform initialization. Override this method instead of
   * {@link #setUp()}. This method is run even in pure Java mode (non-GWT).
   *
   * @see #setForcePureJava
   */
  protected void gwtSetUp() throws Exception {
  }

  /**
   * A replacement for JUnit's {@link #tearDown()} method. This method runs once
   * per test method in your subclass, just after your each test method runs and
   * can be used to perform cleanup. Override this method instead of
   * {@link #tearDown()}. This method is run even in pure Java mode (non-GWT).
   *
   * @see #setForcePureJava
   */
  protected void gwtTearDown() throws Exception {
  }

  /**
   * Runs the test via the {@link JUnitShell} environment. Do not override or
   * call this method.
   */
  @Override
  protected void runTest() throws Throwable {
    if (this.getName() == null) {
      throw new IllegalArgumentException(
          "GWTTestCases require a name; \""
              + this.toString()
              + "\" has none.  Perhaps you used TestSuite.addTest() instead of addTestClass()?");
    }

    if (isPureJava()) {
      super.runTest();
    } else {
      JUnitShell.runTest(this, testResult);
    }
  }

  /**
   * This method has been made final to prevent you from accidentally running
   * client code outside of the GWT environment. Please override
   * {@link #gwtSetUp()} instead.
   */
  @Override
  protected final void setUp() throws Exception {
    if (isPureJava()) {
      gwtSetUp();
    }
  }

  /**
   * This method has been made final to prevent you from accidentally running
   * client code outside of the GWT environment. Please override
   * {@link #gwtTearDown()} instead.
   */
  @Override
  protected final void tearDown() throws Exception {
    if (isPureJava()) {
      gwtTearDown();
    }
  }
}
