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

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.cfg.ConfigurationProperty;
import com.google.gwt.dev.cfg.ModuleDef;
import com.google.gwt.dev.cfg.ModuleDefLoader;
import com.google.gwt.dev.util.collect.HashSet;
import com.google.gwt.junit.JUnitShell.Strategy;
import com.google.gwt.junit.client.GWTTestCase;
import com.google.gwt.junit.client.impl.GWTRunner;
import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
import com.google.gwt.logging.client.LogConfiguration;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * An interface that specifies how modules should be compiled.
 */
public abstract class CompileStrategy {

  /**
   * The list of modules that have already been compiled. We use this to avoid
   * adding test batches that have already been added.
   */
  private Set<String> compiledModuleNames = new HashSet<String>();

  private final JUnitShell junitShell;

  /**
   * Construct a CompileStrategy.
   *
   * @param junitShell
   */
  public CompileStrategy(JUnitShell junitShell) {
    this.junitShell = junitShell;
  }

  /**
   * Maybe add a test block for the currently executed test case.
   *
   * @param testCase the test case being run
   * @param batchingStrategy the batching strategy
   */
  public void maybeAddTestBlockForCurrentTest(GWTTestCase testCase,
      BatchingStrategy batchingStrategy) {
    if (batchingStrategy.isSingleTestOnly()) {
      TestInfo testInfo = new TestInfo(testCase.getSyntheticModuleName(),
          testCase.getClass().getName(), testCase.getName());
      List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>(1);
      testBlocks.add(new TestInfo[]{testInfo});
      getMessageQueue().addTestBlocks(testBlocks, false);
    }
  }

  /**
   * Let the compile strategy compile another module. This is called while
   * {@link JUnitShell} is waiting for the current test to complete.
   *
   * @throws UnableToCompleteException if the compilation fails
   */
  public void maybeCompileAhead() throws UnableToCompleteException {
  }

  /**
   * Compile a single module using a synthetic module that adds JUnit support.
   *
   * @param moduleName the module name
   * @param syntheticModuleName the synthetic module name
   * @param strategy the strategy
   * @param batchingStrategy the batching strategy
   * @param treeLogger the logger
   * @return the {@link ModuleDef} describing the synthetic module
   * @throws UnableToCompleteException
   */
  public abstract ModuleDef maybeCompileModule(String moduleName,
      String syntheticModuleName, Strategy strategy,
      BatchingStrategy batchingStrategy, TreeLogger treeLogger)
      throws UnableToCompleteException;

  /**
   * Compile a single module using a synthetic module that adds JUnit support.
   *
   * @param moduleName the module name
   * @param syntheticModuleName the synthetic module name
   * @param strategy the strategy
   * @param batchingStrategy the batching strategy
   * @param treeLogger the logger
   * @return the {@link ModuleDef} describing the synthetic module
   */
  protected ModuleDef maybeCompileModuleImpl(String moduleName,
      String syntheticModuleName, Strategy strategy,
      BatchingStrategy batchingStrategy, TreeLogger treeLogger)
      throws UnableToCompleteException {

    ModuleDef moduleDef = maybeCompileModuleImpl2(moduleName,
        syntheticModuleName, strategy, treeLogger);

    // Add all test blocks for the module if we haven't seen this module before.
    if (!compiledModuleNames.contains(syntheticModuleName)) {
      compiledModuleNames.add(syntheticModuleName);
      if (!batchingStrategy.isSingleTestOnly()) {
        // Use >= so we can mock getModuleCount and force isFinalModule to true
        boolean isFinalModule = compiledModuleNames.size() >= getModuleCount();
        List<TestInfo[]> testBlocks = batchingStrategy.getTestBlocks(syntheticModuleName);
        getMessageQueue().addTestBlocks(testBlocks, isFinalModule);
      }
    }

    return moduleDef;
  }

  /**
   * Visible for testing and mocking.
   *
   * @return the {@link JUnitMessageQueue}
   */
  JUnitMessageQueue getMessageQueue() {
    return JUnitShell.getMessageQueue();
  }

  /**
   * Visible for testing and mocking.
   *
   * @return the number of modules to test
   */
  int getModuleCount() {
    return GWTTestCase.getModuleCount();
  }

  /**
   * Compile the module if needed.
   *
   * Visible for testing and mocking.
   *
   * @param moduleName the module name
   * @param syntheticModuleName the synthetic module name
   * @param strategy the strategy
   * @param treeLogger the logger
   * @return the {@link ModuleDef} describing the synthetic module
   */
  ModuleDef maybeCompileModuleImpl2(String moduleName,
      String syntheticModuleName, Strategy strategy, TreeLogger treeLogger)
      throws UnableToCompleteException {
    /*
     * Synthesize a synthetic module that derives from the user-specified module
     * but also includes JUnit support.
     */
    ModuleDef moduleDef = ModuleDefLoader.createSyntheticModule(
        treeLogger, junitShell.getCompilerContext(), syntheticModuleName,
        new String[] {moduleName, "com.google.gwt.junit.JUnit"}, false);

    // Replace any user entry points with our test runner.
    moduleDef.clearEntryPoints();

    // LogConfiguration needs to be earlier otherwise it will override UncaughtExceptionHandler.
    moduleDef.addEntryPointTypeName(LogConfiguration.class.getName());
    moduleDef.addEntryPointTypeName(GWTRunner.class.getName());

    // Squirrel away the name of the active module for GWTRunnerGenerator
    ConfigurationProperty moduleNameProp = moduleDef.getProperties().createConfiguration(
        "junit.moduleName", false);
    moduleNameProp.setValue(syntheticModuleName);

    strategy.processModule(moduleDef);

    junitShell.maybeCompileForWebMode(moduleDef, JUnitShell.getRemoteUserAgents());

    return moduleDef;
  }
}
