/*
 * Copyright 2013-present Facebook, 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.facebook.buck.java.abi;

import static com.google.common.base.Charsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.facebook.buck.testutil.integration.TestDataHelper;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.SortedSet;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class AbiWriterTest {

  @Rule public TemporaryFolder temp = new TemporaryFolder();

  @Test
  public void abiKeyForEmptySourcesIsStable() {
    assertEquals(
        "The ABI key used when a java_library() has no srcs should be constant across platforms.",
        AbiWriterProtocol.EMPTY_ABI_KEY,
        AbiWriter.computeAbiKey(ImmutableSortedSet.<String>of()));
  }

  @Test
  public void willCaptureClassName() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {}"));

    assertTrue(summary, summary.contains("public class com.facebook.buck.example.A"));
  }

  @Test
  public void willCaptureTypeParametersOnClass() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A<T> {}"));

    assertTrue(summary, summary.contains("com.facebook.buck.example.A<T>"));
  }

  @Test
  public void classesDefaultToExtendingJavaLangObject() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {}"));

    assertTrue(summary, summary.contains("extends java.lang.Object"));
  }

  @Test
  public void classesCanImplementManyInterfaces() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "import java.io.Serializable;",
        "public class A implements Cloneable, Serializable {}"));

    assertTrue("Ordering of interfaces is alphabetical based on fully qualified name" + summary,
        summary.contains("implements java.io.Serializable, java.lang.Cloneable"));
  }

  @Test
  public void classesCanImplementInterfacesThatHaveAGenericType() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A implements Comparable<A> {",
        "  public int compareTo(A o) {",
        "    return 1;",
        "  }",
        "}"));

    assertTrue(summary,
        summary.contains("implements java.lang.Comparable<com.facebook.buck.example.A>"));
  }

  @Test
  public void runtimeAnnotationsArePreservedAtTheClassLevel() throws IOException{
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "@Deprecated",
        "public class A {}"));

    assertTrue(summary, summary.contains("@java.lang.Deprecated"));
  }

  @Test
  public void classesCanHaveMethods() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public int doSomething(String foo) {",
        "    return 0;",
        "  }",
        "}"));

    assertTrue(summary, summary.contains("public int doSomething(java.lang.String)"));

    // Make sure we've not output the method body.
    assertFalse(summary, summary.contains("return"));
  }

  @Test
  public void genericTypesOnClassMethodsAreCorrectlyReported() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A<Y> {",
        "  public <X> X doSomething(Y foo, A bar, String baz) {",
        "    return null;",
        "  }",
        "}"));

    assertTrue(summary, summary.contains(
        "<X> X doSomething(Y, com.facebook.buck.example.A, java.lang.String)"));
  }

  @Test
  public void retainedAnnotationsOnClassMethodsAreKept() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  @Deprecated public void foo() {}",
        "}"));

    assertTrue(summary, summary.contains("@java.lang.Deprecated"));
  }

  @Test
  public void interfacesDoNotExtendAnything() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "interface A {}"));

    assertTrue(summary, summary.contains("interface com.facebook.buck.example.A"));
  }

  @Test
  public void interfacesCanExtendOtherInterfaces() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "interface A extends java.io.Serializable {}"));

    assertTrue(summary, summary.contains("example.A extends java.io.Serializable"));
  }

  @Test
  public void interfacesRetainClassLevelAnnotations() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "@Deprecated public interface A {}"));

    assertTrue(summary, summary.contains("@java.lang.Deprecated"));
  }

  @Test
  public void interfacesCanBeTyped() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public interface A<T> {}"));

    assertEquals("public abstract interface com.facebook.buck.example.A<T>\n", summary);
  }

  @Test
  public void interfaceMethodsAreReported() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public interface A {",
        "  public int doSomething(String foo);",
        "  void sitQuietly();",
        "}"));

    assertTrue(summary, summary.contains("public abstract int doSomething(java.lang.String)"));
    assertTrue(summary, summary.contains("public abstract void sitQuietly()"));
  }

  @Test
  public void interfaceMethodsWithTypeSignaturesAreCorrectlyKept() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public interface A<Y> {",
        "  public <X> X doSomething(Y foo, A bar, String baz);",
        "}"));

    assertTrue(summary, summary.contains(
        "<X> X doSomething(Y, com.facebook.buck.example.A, java.lang.String)"));
  }

  @Test
  public void shouldNotIncludePrivateMethods() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  private void doSomething() {}",
        "}"));

    assertFalse(summary, summary.contains("doSomething"));
  }

  // Fields
  @Test
  public void visibleFieldsAreIncluded() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
      "package com.facebook.buck.example;",
      "public class A {",
      "  public int number = 42;",
      "  private String magic = \"Now you see me\";",
      "}"));

    assertTrue(summary, summary.contains("public int number"));
    assertFalse(summary, summary.contains("42"));
    assertFalse(summary, summary.contains("magic"));
  }

  @Test
  public void runTimeAnnotationsOnFieldsAreRetained() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  @Deprecated",
        "  public int number;",
        "}"));

    assertTrue(summary, summary.contains("@java.lang.Deprecated"));
  }

  @Test
  public void genericTypesOnFieldsAreKept() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "import java.util.Set;",
        "public class A {",
        "  public Set<String> strings;",
        "}"));

    assertTrue(summary, summary.contains("Set<java.lang.String> strings"));
  }

  @Test
  public void shouldMaintainWildCardGenerics() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "import java.util.Set;",
        "public class A {",
        "  public Set<?> question;",
        "}"));

    assertTrue(summary, summary.contains("Set<?> question"));
  }

  @Test
  public void shouldComplexGenerics() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "import java.util.Collection;",
        "import java.util.Set;",
        "public class A<T> {",
        "  public Set<? extends Collection> extension;",
        "  public Set<? super T> supered;",
        "}"));

    assertTrue(summary, summary.contains("Set<? extends java.util.Collection> extension"));
    assertTrue(summary, summary.contains("Set<? super T> supered"));
  }

  @Test
  public void nestedGenericsAreOkay() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "import java.util.Collection;",
        "import java.util.Set;",
        "public class A<T> {",
        "  public Set<Collection<String>> nested;",
        "}"));

    assertTrue(summary,
        summary.contains("java.util.Set<java.util.Collection<java.lang.String>> nested"));
  }

  // Constants
  @Test
  public void compileTimeConstantExpressionsAreRetainedOnFields() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public final static int NUMBER = 42;",
        "  final static String MAGIC = \"Now you see me\" + 3;",
        "  public static int foo = 37;",
        "  public static final long NOW = System.currentTimeMillis();",
        "}"));

    assertTrue(summary, summary.contains("public static final int NUMBER = 42"));
    assertTrue(summary, summary.contains("static final java.lang.String MAGIC = Now you see me3"));
    assertFalse(summary, summary.contains("public static int foo = 37"));
    assertTrue(summary, summary.contains("public static final long NOW\n"));
  }

  @Test
  public void checkThatDefinedInOtherClassesThatCanBeInlinedAreInlined() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public final static int NUMBER = 42;",
        "  final static String MAGIC = \"Now you see me\" + 3;",
        "  public static int foo = 37;",
        "  public static final long NOW = System.currentTimeMillis();",
        "}"),
        "B.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class B {",
        "  public final static int KEY = A.NUMBER + 3;",
        "}"
        ));

    assertTrue(summary, summary.contains("KEY = 45"));
  }

  // Enums
  @Test
  public void enumsAreHandled() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public enum A {",
        "  ONE, TWO, THREE;",
        "  public void doSomething() {} ",
        "}"));

    assertTrue(summary, summary.contains("ONE"));
    assertTrue(summary, summary.contains("TWO"));
    assertTrue(summary, summary.contains("THREE"));
    assertTrue(summary, summary.contains("public void doSomething()"));
  }

  @Test
  public void orderingOfEnumConstantsMatters() throws IOException {
    String first = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public enum A {",
        "  ONE, TWO;",
        "  public void doSomething() {} ",
        "}"));

    String second = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public enum A {",
        "  TWO, ONE;",
        "  public void doSomething() {} ",
        "}"));

    assertNotEquals(first, second);
  }

  @Test
  public void canHandleNewAnnotationTypes() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "import java.lang.annotation.*;",
        "import static java.lang.annotation.ElementType.*;",
        "@Retention(RetentionPolicy.RUNTIME)",
        "@Target(value={CONSTRUCTOR, FIELD})",
        "public @interface A {}"));

    assertTrue(summary, summary.contains("@interface com.facebook.buck.example.A"));
    assertTrue(summary, summary.contains(
        "@java.lang.annotation.Retention(value=java.lang.annotation.RetentionPolicy.RUNTIME)"));
    assertTrue(summary, summary.contains(
        "@java.lang.annotation.Target(value={java.lang.annotation.ElementType.CONSTRUCTOR,"));
  }


  @Test
  public void innerClassesCanBeNested() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public static class B {",
        "    public void foo() {}",
        "  }",
        "}"));

    assertTrue(summary, summary.contains(
        "public static class com.facebook.buck.example.A.B extends java.lang.Object"));
  }

  @Test
  public void innerClassesCanBeDeeplyNested() throws IOException {
    String summary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public static class B {",
        "    public class C {",
        "      public void foo() {}",
        "    }",
        "  }",
        "}"));

    assertTrue(summary,
        summary.contains("public class com.facebook.buck.example.A.B.C extends java.lang.Object"));
  }

  @Test
  public void abisOfAClassAndAInterfaceWithSharedMethodsAreNotTheSame() throws IOException {
    String classSummary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public abstract class A {",
        "  public abstract void doSomething();",
        "}"));

    String interfaceSummary = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public interface A {",
        "  void doSomething();",
        "}"));

    assertNotEquals(classSummary, interfaceSummary);
  }

  @Test
  public void reorderingFieldsDoesNotModifyTheAbi() throws IOException {
    String original = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public int first;",
        "  public int second;",
        "}"));

    String abiCompatible = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public int second;",
        "  public int first;",
        "}"));

    assertEquals(original, abiCompatible);
  }

  @Test
  public void reorderingMethodsDoesNotModifyTheAbi() throws IOException {
    String original = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public void doSomething() {}",
        "  public int aLongRunningComputation() { return 42; }",
        "}"));

    String abiCompatible = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public int aLongRunningComputation() { return 2345; }",
        "  public void doSomething() {}",
        "}"));

    assertEquals(original, abiCompatible);
  }

  @Test
  public void renamingMethodArgumentsDoesNotModifyTheAbi() throws IOException {
    String original = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public void doSomething(int count) {}",
        "}"));

    String abiCompatible = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public void doSomething(int numberOfTimes) {}",
        "}"));

    assertEquals(original, abiCompatible);
  }

  @Test
  public void varargsAreNotTheSameAsArrays() throws IOException {
    String original = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public void doSomething(String... args) {}",
        "}"));

    String amended = compile("A.java", Joiner.on("\n").join(
        "package com.facebook.buck.example;",
        "public class A {",
        "  public void doSomething(String[] args) {}",
        "}"));

    assertNotEquals(original, amended);
  }

  @Test
  public void generateSampleOutput() throws IOException {
    File testDataDir = TestDataHelper.getTestDataScenario(this, "compute_abi");
    String source = Files.toString(
        new File(testDataDir, "generateSampleOutput.src"), UTF_8);
    String original = compile("A.java", source);

    String expected = Files.toString(
        new File(testDataDir, "generateSampleOutput.expected"), UTF_8);

    assertEquals(expected, original);
  }

  @Test
  public void generatedHashMustBeZeroPaddedToFortyCharacters() {
    String hex = AbiWriter.computeAbiKey(ImmutableSortedSet.of("abcdefghi"));

    assertEquals('0', hex.charAt(0));
    assertEquals(40, hex.length());
  }

  @Test
  public void shouldIgnoreAnnotatedPackageDeclarations() throws IOException {
    Optional<String> compiled = getOptionalSummary(
        "package-info.java",
        Joiner.on("\n").join(
            "/** This is a documented pacakge */",
            "@Deprecated",  // It's legit to deprecate an entire package
            "package com.facebook.buck.example;"));

    // If we get this far, then we know that everything is just fine. We're just preventing an
    // exception being thrown, and it's impossible to accidentally have a java class called
    // "package-info" so we're not expecting this to contribute to the API.
    assertFalse(compiled.isPresent());
  }

  @Test
  public void shouldIgnoreUnannotatedPackageDeclarations() throws IOException {
    Optional<String> compiled = getOptionalSummary(
        "package-info.java",
        Joiner.on("\n").join(
            "/** This is a documented pacakge without an annotation */",
            "package com.facebook.buck.example;"));

    assertFalse(compiled.isPresent());
  }

  @Test
  public void emptySummariesLeadToAnEmptyAbiKeyBeingMade() throws IOException {
    File outDir = temp.newFolder();
    File onlyDocs = new File(outDir, "package-info.java");
    SortedSet<String> summaries = generateSummary(
        outDir,
        new FileAndSource(onlyDocs,
            Joiner.on("\n").join(
                "/** This is a package */",
                "package com.facebook.buck.example;")),
        ImmutableSet.<File>of());

    assertTrue(summaries.isEmpty());

    String computed = AbiWriter.computeAbiKey(summaries);

    assertEquals(AbiWriterProtocol.EMPTY_ABI_KEY, computed);
  }

  @Test
  public void ensureHashMatchesGuavaEquivalent() {
    String key = AbiWriter.computeAbiKey(ImmutableSortedSet.<String>of());
    String guava = hashWithGuava(ImmutableSortedSet.<String>of());
    assertEquals(guava, key);

    String javaCode = Joiner.on('\n').join(
        "public class Example",
        "public void cheese(java.lang.String)");

    SortedSet<String> summaries = ImmutableSortedSet.of(javaCode);
    key = AbiWriter.computeAbiKey(summaries);
    guava = hashWithGuava(summaries);
    assertEquals(guava, key);
  }

  private String hashWithGuava(SortedSet<String> summaries) {
    Hasher hasher = Hashing.sha1().newHasher();
    for (String summary : summaries) {
      hasher.putUnencodedChars(summary);
    }
    return hasher.hash().toString();
  }

  /**
   * Files are compiled in the order that they're fed to this method. As each file is compiled its
   * output directory is added to a classpath that lives for the duration of the method call. As
   * each file is compiled, the summaries generated by AbiWriter for the last compilation are
   * stored.
   *
   * @return the summary of the last file to be compiled.
   */
  private String compile(
      String fileName, String source, String... fileNamesAndSources) throws IOException {
    return getOptionalSummary(fileName, source, fileNamesAndSources).get();
  }

  private Optional<String> getOptionalSummary(
      String fileName, String source, String... fileNamesAndSources) throws IOException {
    List<FileAndSource> targets = Lists.newArrayList();

    targets.add(new FileAndSource(new File(temp.newFolder(), fileName), source));
    for (int i = 0; i < fileNamesAndSources.length; i++) {
      targets.add(new FileAndSource(
          new File(temp.newFolder(), fileNamesAndSources[i++]), fileNamesAndSources[i]));
    }

    ImmutableSet.Builder<File> classpath = ImmutableSet.builder();
    SortedSet<String> lastSummary = null;
    for (FileAndSource target : targets) {
      File outputDir = temp.newFolder();
      lastSummary = generateSummary(outputDir, target, classpath.build());
      classpath.add(outputDir);
    }
    if (lastSummary.isEmpty()) {
      return Optional.absent();
    }
    return Optional.of(Iterables.getOnlyElement(lastSummary));
  }


  private SortedSet<String> generateSummary(
      File outputDir,
      FileAndSource target,
      ImmutableSet<File> classpath) throws IOException{
    File file = target.file;
    Files.write(target.source, file, UTF_8);

    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    Iterable<? extends JavaFileObject> sourceObjects =
        fileManager.getJavaFileObjectsFromFiles(ImmutableSet.of(file));

    List<String> args = Lists.newArrayList("-g", "-d", outputDir.getAbsolutePath());
    if (!classpath.isEmpty()) {
      args.add("-classpath");
      args.add(Joiner.on(File.pathSeparator).join(classpath));
    }

    AbiWriter processor = new AbiWriter();

    JavaCompiler.CompilationTask compilation =
        compiler.getTask(null, fileManager, null, args, null, sourceObjects);
    compilation.setProcessors(ImmutableSet.of(processor));

    Boolean result = compilation.call();
    assertNotNull(result);
    assertTrue(result);

    return processor.getSummaries();
  }

  private static class FileAndSource {
    public File file;
    public String source;

    public FileAndSource(File file, String source) {
      this.file = file;
      this.source = source;
    }
  }
}
