/*
 * Copyright 2014 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.codeserver;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.MinimalRebuildCacheManager;
import com.google.gwt.dev.codeserver.Job.Result;
import com.google.gwt.dev.javac.UnitCache;
import com.google.gwt.dev.javac.UnitCacheSingleton;
import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.javac.testing.impl.MockResource;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.thirdparty.guava.common.base.Charsets;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableMap;
import com.google.gwt.thirdparty.guava.common.collect.Lists;
import com.google.gwt.thirdparty.guava.common.io.Files;

import junit.framework.TestCase;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Tests for {@link Recompiler}
 */
public class RecompilerTest extends TestCase {

  private static File findCompiledJsFile(Result result) {
    File outputDir = new File(result.outputDir.getWarDir(), result.outputModuleName);
    File[] files = outputDir.listFiles(new FilenameFilter() {
      @Override
      public boolean accept(File dir, String name) {
        return name.endsWith(".js") && !name.endsWith("nocache.js");
      }
    });
    Arrays.sort(files, new Comparator<File>() {
      @Override
      public int compare(File thisFile, File thatFile) {
        return -Long.compare(thisFile.length(), thatFile.length());
      }
    });
    return files[0];
  }

  private static void writeResourcesTo(List<MockResource> resources, File dir) throws IOException {
    for (MockResource applicationResource : resources) {
      File resourceFile =
          new File(dir.getAbsolutePath() + File.separator + applicationResource.getPath());
      resourceFile.getParentFile().mkdirs();
      Files.write(applicationResource.getContent(), resourceFile, Charsets.UTF_8);
    }
  }

  private MockJavaResource barReferencesBazResource =
      JavaResourceBase.createMockJavaResource("com.foo.Bar",
          "package com.foo;",
          "public class Bar {",
          "  Baz baz = new Baz();",
          "}");

  private MockJavaResource bazReferencesFooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Baz",
          "package com.foo;",
          "public class Baz {",
          "  Foo foo = new Foo();",
          "}");

  private MockJavaResource fooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "public class Foo {}");

  private MockJavaResource nonCompilableFooResource =
      JavaResourceBase.createMockJavaResource("com.foo.Foo",
          "package com.foo;",
          "import com.google.gwt.core.client.impl.SpecializeMethod;",
          "public class Foo {",
          "  // This will throw an error in UnifyAst.",
          "  @SpecializeMethod()",
          "  public void run() {}",
          "}");

  private MockJavaResource referencesBarEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.TestEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "public class TestEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    Bar bar = new Bar();",
          "  }",
          "}");

  private MockResource simpleModuleResource =
      JavaResourceBase.createMockResource("com/foo/SimpleModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.TestEntryPoint'/>",
          "</module>");

  private MockResource propertyIsFooModuleResource =
      JavaResourceBase.createMockResource("com/foo/PropertyModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.PropertyEntryPoint'/>",
          "<define-property name=\"target\" values=\"foo,bar\" />",
          "<set-property name=\"target\" value=\"foo\" />",
          "<replace-with class=\"com.foo.Foo\">",
          "  <when-type-is class=\"com.foo.Bar\"/>",
          "  <when-property-is name=\"target\" value=\"foo\"/>",
          "</replace-with>",
          "</module>");

  private MockResource propertyIsBarModuleResource =
      JavaResourceBase.createMockResource("com/foo/PropertyModule.gwt.xml",
          "<module>",
          "<source path=''/>",
          "<entry-point class='com.foo.PropertyEntryPoint'/>",
          "<define-property name=\"target\" values=\"foo,bar\" />",
          "<set-property name=\"target\" value=\"bar\" />",
          "<replace-with class=\"com.foo.Foo\">",
          "  <when-type-is class=\"com.foo.Bar\"/>",
          "  <when-property-is name=\"target\" value=\"foo\"/>",
          "</replace-with>",
          "</module>");

  private MockJavaResource performsRebindEntryPointResource =
      JavaResourceBase.createMockJavaResource("com.foo.PropertyEntryPoint",
          "package com.foo;",
          "import com.google.gwt.core.client.EntryPoint;",
          "import com.google.gwt.core.client.GWT;",
          "public class PropertyEntryPoint implements EntryPoint {",
          "  @Override",
          "  public void onModuleLoad() {",
          "    GWT.create(Bar.class);",
          "  }",
          "}");

  public void testIncrementalRecompile_compileErrorDoesntCorruptMinimalRebuildCache()
      throws UnableToCompleteException, IOException, InterruptedException {
    String moduleName = "com.foo.SimpleModule";
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
    logger.setMaxDetail(TreeLogger.ERROR);

    File sourcePath = Files.createTempDir();
    // Setup options to perform a per-file compile and compile the given module.
    Options options = new Options();
    options.parseArgs(new String[] {
        "-incremental", "-src", sourcePath.getAbsolutePath(), moduleName});

    // Prepare the basic resources in the test application.
    List<MockResource> originalResources = Lists.newArrayList(simpleModuleResource,
        referencesBarEntryPointResource, barReferencesBazResource, bazReferencesFooResource,
        fooResource);
    writeResourcesTo(originalResources, sourcePath);

    File baseCacheDir = Files.createTempDir();
    UnitCache unitCache = UnitCacheSingleton.get(
        logger, null, baseCacheDir, new CompilerOptionsImpl(options));
    MinimalRebuildCacheManager minimalRebuildCacheManager =
        new MinimalRebuildCacheManager(logger, baseCacheDir, ImmutableMap.<String, String>of());
    Recompiler recompiler = new Recompiler(OutboxDir.create(Files.createTempDir(), logger), null,
        moduleName, options, unitCache, minimalRebuildCacheManager);
    Outbox outbox = new Outbox("Transactional Cache", recompiler, options, logger);
    OutboxTable outboxTable = new OutboxTable();
    outboxTable.addOutbox(outbox);
    JobRunner runner = new JobRunner(new JobEventTable(), minimalRebuildCacheManager);

    // Perform a first compile. This should pass since all resources are valid.
    Result result =
        compileWithChanges(logger, runner, outbox, sourcePath, Lists.<MockResource> newArrayList());
    assertTrue(result.isOk());

    // Recompile should fail since the provided Foo is not compilable.
    result = compileWithChanges(logger, runner, outbox, sourcePath,
        Lists.<MockResource> newArrayList(nonCompilableFooResource));
    assertFalse(result.isOk());

    // Recompile with a modified entry point. This should fail again since Foo is still
    // bad, but if transactionality protection failed on the minimalRebuildCache this compile will
    // succeed because it will think that it has "already processed" Foo.
    result = compileWithChanges(logger, runner, outbox, sourcePath,
        Lists.<MockResource> newArrayList(referencesBarEntryPointResource));
    assertFalse(result.isOk());
  }

  public void testIncrementalRecompile_modulePropertyEditsWork() throws UnableToCompleteException,
      IOException, InterruptedException {
    String moduleName = "com.foo.PropertyModule";
    PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
    logger.setMaxDetail(TreeLogger.ERROR);

    File sourcePath = Files.createTempDir();
    // Setup options to perform a per-file compile and compile the given module.
    Options options = new Options();
    options.parseArgs(new String[] {
        "-incremental", "-src", sourcePath.getAbsolutePath(), moduleName});

    // Prepare the basic resources in the test application.
    List<MockResource> originalResources = Lists.newArrayList(propertyIsFooModuleResource,
        performsRebindEntryPointResource, barReferencesBazResource, bazReferencesFooResource,
        fooResource);
    writeResourcesTo(originalResources, sourcePath);

    File baseCacheDir = Files.createTempDir();
    UnitCache unitCache = UnitCacheSingleton.get(
        logger, null, baseCacheDir, new CompilerOptionsImpl(options));
    MinimalRebuildCacheManager minimalRebuildCacheManager =
        new MinimalRebuildCacheManager(logger, baseCacheDir, ImmutableMap.<String, String>of());
    Recompiler recompiler = new Recompiler(OutboxDir.create(Files.createTempDir(), logger), null,
        moduleName, options, unitCache, minimalRebuildCacheManager);
    Outbox outbox = new Outbox("Transactional Cache", recompiler, options, logger);
    OutboxTable outboxTable = new OutboxTable();
    outboxTable.addOutbox(outbox);
    JobRunner runner = new JobRunner(new JobEventTable(), minimalRebuildCacheManager);

    // Perform a first compile with configuration to rebind Bar to Foo.
    Result result =
        compileWithChanges(logger, runner, outbox, sourcePath, Lists.<MockResource> newArrayList());
    assertTrue(result.isOk());
    File compiledJsFile1 = findCompiledJsFile(result);

    // Perform a second compile with a changed property value that will result in NOT rebinding Bar
    // to Foo.
    result = compileWithChanges(logger, runner, outbox, sourcePath,
        Lists.<MockResource> newArrayList(propertyIsBarModuleResource));
    assertTrue(result.isOk());
    File compiledJsFile2 = findCompiledJsFile(result);

    // The compiled Js files are different files on disk and their contents are not the same as
    // evidenced by their names being different (the names are a hash of content).
    assertFalse(compiledJsFile1.equals(compiledJsFile2));
    assertFalse(compiledJsFile1.getName().equals(compiledJsFile2.getName()));
  }

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    // Make sure we're using a MemoryUnitCache.
    System.setProperty(UnitCacheSingleton.GWT_PERSISTENTUNITCACHE, "false");
  }

  private Result compileWithChanges(TreeLogger logger, JobRunner runner, Outbox outbox,
      File sourcePath, List<MockResource> changedResources) throws InterruptedException,
      IOException {
    // Wait 1 second so that any new file modification times are actually different.
    Thread.sleep(1001);

    // Write the Java/XML/etc resources that make up the test application.
    writeResourcesTo(changedResources, sourcePath);

    // Compile and return success status.
    Map<String, String> bindingProperties = new HashMap<String, String>();
    Job job = outbox.makeJob(bindingProperties, logger);
    runner.submit(job);
    return job.waitForResult();
  }
}
