/*
 * Copyright 2015 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.googlejavaformat.java;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;

import com.google.common.base.Joiner;
import com.google.common.io.CharStreams;
import com.google.googlejavaformat.java.JavaFormatterOptions.Style;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Integration test for google-java-format. */
@RunWith(JUnit4.class)
public final class FormatterTest {

  @Rule public TemporaryFolder testFolder = new TemporaryFolder();

  @Test
  public void testFormatAosp() throws Exception {
    // don't forget to misspell "long", or you will be mystified for a while
    String input =
        "class A{void b(){while(true){weCanBeCertainThatThisWillEndUpGettingWrapped("
            + "because, it, is, just, so, very, very, very, very, looong);}}}";
    String expectedOutput =
        Joiner.on("\n")
            .join(
                "class A {",
                "    void b() {",
                "        while (true) {",
                "            weCanBeCertainThatThisWillEndUpGettingWrapped(",
                "                    because, it, is, just, so, very, very, very, very, looong);",
                "        }",
                "    }",
                "}",
                "");

    Path tmpdir = testFolder.newFolder().toPath();
    Path path = tmpdir.resolve("A.java");
    Files.write(path, input.getBytes(StandardCharsets.UTF_8));

    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();

    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);
    String[] args = {"--aosp", path.toString()};
    assertThat(main.format(args)).isEqualTo(0);
    assertThat(out.toString()).isEqualTo(expectedOutput);
  }

  @Test
  public void testFormatNonJavaFiles() throws Exception {
    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();
    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);

    // should succeed because non-Java files are skipped
    assertThat(main.format("foo.go")).isEqualTo(0);
    assertThat(err.toString()).contains("Skipping non-Java file: " + "foo.go");

    // format still fails on missing files
    assertThat(main.format("Foo.java")).isEqualTo(1);
    assertThat(err.toString()).contains("Foo.java: could not read file: ");
  }

  @Test
  public void testFormatStdinStdoutWithDashFlag() throws Exception {
    String input = "class Foo{\n" + "void f\n" + "() {\n" + "}\n" + "}\n";
    String expectedOutput = "class Foo {\n" + "  void f() {}\n" + "}\n";

    InputStream in = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();

    InputStream oldIn = System.in;
    System.setIn(in);

    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);
    assertThat(main.format("-")).isEqualTo(0);
    assertThat(out.toString()).isEqualTo(expectedOutput);

    System.setIn(oldIn);
  }

  @Test
  public void testFormatLengthUpToEOF() throws Exception {
    String input = "class Foo{\n" + "void f\n" + "() {\n" + "}\n" + "}\n\n\n\n\n\n";
    String expectedOutput = "class Foo {\n" + "  void f() {}\n" + "}\n";

    Path tmpdir = testFolder.newFolder().toPath();
    Path path = tmpdir.resolve("Foo.java");
    Files.write(path, input.getBytes(StandardCharsets.UTF_8));

    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();

    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);
    String[] args = {"--offset", "0", "--length", String.valueOf(input.length()), path.toString()};
    assertThat(main.format(args)).isEqualTo(0);
    assertThat(out.toString()).isEqualTo(expectedOutput);
  }

  @Test
  public void testFormatLengthOutOfRange() throws Exception {
    String input = "class Foo{}\n";

    Path tmpdir = testFolder.newFolder().toPath();
    Path path = tmpdir.resolve("Foo.java");
    Files.write(path, input.getBytes(StandardCharsets.UTF_8));

    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();

    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);
    String[] args = {"--offset", "0", "--length", "9999", path.toString()};
    assertThat(main.format(args)).isEqualTo(1);
    assertThat(err.toString())
        .contains("error: invalid length 9999, offset + length (9999) is outside the file");
  }

  @Test
  public void blankInClassBody() throws FormatterException {
    String input = "package test;\nclass T {\n\n}\n";
    String output = new Formatter().formatSource(input);
    String expect = "package test;\n\nclass T {}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void blankInClassBodyNoTrailing() throws FormatterException {
    String input = "package test;\nclass T {\n\n}";
    String output = new Formatter().formatSource(input);
    String expect = "package test;\n\nclass T {}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void docCommentTrailingBlank() throws FormatterException {
    String input = "class T {\n/** asd */\n\nint x;\n}";
    String output = new Formatter().formatSource(input);
    String expect = "class T {\n  /** asd */\n  int x;\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void blockCommentInteriorTrailingBlank() throws FormatterException {
    String input = "class T {\n/*\n* asd \n* fgh\n*/ \n\nint x;\n}";
    String output = new Formatter().formatSource(input);
    String expect = "class T {\n  /*\n   * asd\n   * fgh\n   */\n\n  int x;\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void blockCommentTrailingBlank() throws FormatterException {
    String input = "class T {\n/* asd */ \n\nint x;\n}";
    String output = new Formatter().formatSource(input);
    String expect = "class T {\n  /* asd */\n\n  int x;\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void lineCommentTrailingBlank() throws FormatterException {
    String input = "class T {\n// asd \n\nint x;\n}";
    String output = new Formatter().formatSource(input);
    String expect = "class T {\n  // asd\n\n  int x;\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void lineCommentTrailingThinSpace() throws FormatterException {
    // The Unicode thin space is matched by CharMatcher.whitespace() but not trim().
    String input = "class T {\n  // asd\u2009\n}\n";
    String output = new Formatter().formatSource(input);
    String expect = "class T {\n  // asd\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void noBlankAfterLineCommentWithInteriorBlankLine() throws FormatterException {
    String input = "class T {\n// asd \n\n// dsa \nint x;\n}";
    String output = new Formatter().formatSource(input);
    String expect = "class T {\n  // asd\n\n  // dsa\n  int x;\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void badConstructor() throws FormatterException {
    String input = "class X { Y() {} }";
    String output = new Formatter().formatSource(input);
    String expect = "class X {\n  Y() {}\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void voidMethod() throws FormatterException {
    String input = "class X { void Y() {} }";
    String output = new Formatter().formatSource(input);
    String expect = "class X {\n  void Y() {}\n}\n";
    assertThat(output).isEqualTo(expect);
  }

  private static final String UNORDERED_IMPORTS =
      Joiner.on('\n')
          .join(
              "import com.google.common.base.Preconditions;",
              "",
              "import static org.junit.Assert.fail;",
              "import static com.google.truth.Truth.assertThat;",
              "",
              "import org.junit.runners.JUnit4;",
              "import org.junit.runner.RunWith;",
              "",
              "import java.util.List;",
              "",
              "import javax.annotations.Nullable;");

  @Test
  public void importsNotReorderedByDefault() throws FormatterException {
    String input =
        "package com.google.example;\n" + UNORDERED_IMPORTS + "\npublic class ExampleTest {}\n";
    String output = new Formatter().formatSource(input);
    String expect =
        "package com.google.example;\n\n" + UNORDERED_IMPORTS + "\n\npublic class ExampleTest {}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void importsFixedIfRequested() throws FormatterException {
    String input =
        "package com.google.example;\n"
            + UNORDERED_IMPORTS
            + "\npublic class ExampleTest {\n"
            + "  @Nullable List<?> xs;\n"
            + "}\n";
    String output = new Formatter().formatSourceAndFixImports(input);
    String expect =
        "package com.google.example;\n\n"
            + "import java.util.List;\n"
            + "import javax.annotations.Nullable;\n\n"
            + "public class ExampleTest {\n"
            + "  @Nullable List<?> xs;\n"
            + "}\n";
    assertThat(output).isEqualTo(expect);
  }

  @Test
  public void importOrderingWithoutFormatting() throws IOException, UsageException {
    importOrdering(
        "--fix-imports-only", "com/google/googlejavaformat/java/testimports/A.imports-only");
  }

  @Test
  public void importOrderingAndFormatting() throws IOException, UsageException {
    importOrdering(null, "com/google/googlejavaformat/java/testimports/A.imports-and-formatting");
  }

  @Test
  public void formattingWithoutImportOrdering() throws IOException, UsageException {
    importOrdering(
        "--skip-sorting-imports",
        "com/google/googlejavaformat/java/testimports/A.formatting-and-unused-import-removal");
  }

  @Test
  public void formattingWithoutRemovingUnusedImports() throws IOException, UsageException {
    importOrdering(
        "--skip-removing-unused-imports",
        "com/google/googlejavaformat/java/testimports/A.formatting-and-import-sorting");
  }

  private void importOrdering(String sortArg, String outputResourceName)
      throws IOException, UsageException {
    Path tmpdir = testFolder.newFolder().toPath();
    Path path = tmpdir.resolve("Foo.java");

    String inputResourceName = "com/google/googlejavaformat/java/testimports/A.input";
    String input = getResource(inputResourceName);
    String expectedOutput = getResource(outputResourceName);
    Files.write(path, input.getBytes(StandardCharsets.UTF_8));

    StringWriter out = new StringWriter();
    StringWriter err = new StringWriter();
    Main main = new Main(new PrintWriter(out, true), new PrintWriter(err, true), System.in);
    String[] args =
        sortArg != null
            ? new String[] {sortArg, "-i", path.toString()}
            : new String[] {"-i", path.toString()};
    main.format(args);

    assertThat(err.toString()).isEmpty();
    assertThat(out.toString()).isEmpty();
    String output = new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
    assertThat(output).isEqualTo(expectedOutput);
  }

  private String getResource(String resourceName) throws IOException {
    try (InputStream stream = getClass().getClassLoader().getResourceAsStream(resourceName)) {
      assertWithMessage("Missing resource: " + resourceName).that(stream).isNotNull();
      return CharStreams.toString(new InputStreamReader(stream, StandardCharsets.UTF_8));
    }
  }

  // regression test for google-java-format#47
  @Test
  public void testTrailingCommentWithoutTerminalNewline() throws Exception {
    assertThat(new Formatter().formatSource("/*\n * my comment */"))
        .isEqualTo("/*\n * my comment */\n");
  }

  @Test
  public void testEmptyArray() throws Exception {
    assertThat(new Formatter().formatSource("class T { int x[] = {,}; }"))
        .isEqualTo("class T {\n  int x[] = {,};\n}\n");
  }

  @Test
  public void stringEscapeLength() throws Exception {
    assertThat(new Formatter().formatSource("class T {{ f(\"\\\"\"); }}"))
        .isEqualTo("class T {\n  {\n    f(\"\\\"\");\n  }\n}\n");
  }

  @Test
  public void wrapLineComment() throws Exception {
    assertThat(
            new Formatter()
                .formatSource(
                    "class T {\n"
                        + "  public static void main(String[] args) { // one long incredibly"
                        + " unbroken sentence moving from topic to topic so that no-one had a"
                        + " chance to interrupt;\n"
                        + "  }\n"
                        + "}\n"))
        .isEqualTo(
            "class T {\n"
                + "  public static void main(\n"
                + "      String[]\n"
                + "          args) { // one long incredibly unbroken sentence moving"
                + " from topic to topic so that no-one\n"
                + "                  // had a chance to interrupt;\n"
                + "  }\n"
                + "}\n");
  }

  @Test
  public void onlyWrapLineCommentOnWhitespace() throws Exception {
    assertThat(
            new Formatter()
                .formatSource(
                    "class T {\n"
                        + "  public static void main(String[] args) { // one_long_incredibly"
                        + "_unbroken_sentence_moving_from_topic_to_topic_so_that_no-one_had_a"
                        + "_chance_to_interrupt;\n"
                        + "  }\n"
                        + "}\n"))
        .isEqualTo(
            "class T {\n"
                + "  public static void main(\n"
                + "      String[]\n"
                + "          args) { // one_long_incredibly"
                + "_unbroken_sentence_moving_from_topic_to_topic_so_that_no-one_had_a"
                + "_chance_to_interrupt;\n"
                + "  }\n"
                + "}\n");
  }

  @Test
  public void onlyWrapLineCommentOnWhitespace_noLeadingWhitespace() throws Exception {
    assertThat(
            new Formatter()
                .formatSource(
                    "class T {\n"
                        + "  public static void main(String[] args) { //one_long_incredibly"
                        + "_unbroken_sentence_moving_from_topic_to_topic_so_that_no-one_had_a"
                        + "_chance_to_interrupt;\n"
                        + "  }\n"
                        + "}\n"))
        .isEqualTo(
            "class T {\n"
                + "  public static void main(\n"
                + "      String[]\n"
                + "          args) { // one_long_incredibly"
                + "_unbroken_sentence_moving_from_topic_to_topic_so_that_no-one_had_a"
                + "_chance_to_interrupt;\n"
                + "  }\n"
                + "}\n");
  }

  @Test
  public void throwsFormatterException() throws Exception {
    try {
      new Formatter().formatSourceAndFixImports("package foo; public class {");
      fail();
    } catch (FormatterException expected) {
    }
  }

  @Test
  public void blankLinesImportComment() throws FormatterException {
    String withBlank =
        "package p;\n"
            + "\n"
            + "/** test */\n"
            + "\n"
            + "import a.A;\n"
            + "\n"
            + "class T {\n"
            + "  A a;\n"
            + "}\n";
    String withoutBlank =
        "package p;\n"
            + "\n"
            + "/** test */\n"
            + "import a.A;\n"
            + "\n"
            + "class T {\n"
            + "  A a;\n"
            + "}\n";

    // Formatting deletes the blank line between the "javadoc" and the first import.
    assertThat(new Formatter().formatSource(withBlank)).isEqualTo(withoutBlank);
    assertThat(new Formatter().formatSourceAndFixImports(withBlank)).isEqualTo(withoutBlank);
    assertThat(new Formatter().formatSource(withoutBlank)).isEqualTo(withoutBlank);
    assertThat(new Formatter().formatSourceAndFixImports(withoutBlank)).isEqualTo(withoutBlank);

    // Just fixing imports preserves whitespace around imports.
    assertThat(RemoveUnusedImports.removeUnusedImports(withBlank)).isEqualTo(withBlank);
    assertThat(ImportOrderer.reorderImports(withBlank, Style.GOOGLE)).isEqualTo(withBlank);
    assertThat(RemoveUnusedImports.removeUnusedImports(withoutBlank)).isEqualTo(withoutBlank);
    assertThat(ImportOrderer.reorderImports(withoutBlank, Style.GOOGLE)).isEqualTo(withoutBlank);
  }

  @Test
  public void dontWrapMoeLineComments() throws Exception {
    assertThat(
            new Formatter()
                .formatSource(
                    "class T {\n"
                        + "  // MOE: one long incredibly"
                        + " unbroken sentence moving from topic to topic so that no-one had a"
                        + " chance to interrupt;\n"
                        + "}\n"))
        .isEqualTo(
            "class T {\n"
                + "  // MOE: one long incredibly"
                + " unbroken sentence moving from topic to topic so that no-one had a"
                + " chance to interrupt;\n"
                + "}\n");
  }

  @Test
  public void removeTrailingTabsInComments() throws Exception {
    assertThat(
            new Formatter()
                .formatSource(
                    "class Foo {\n"
                        + "  void f() {\n"
                        + "    int x = 0; // comment\t\t\t\n"
                        + "    return;\n"
                        + "  }\n"
                        + "}\n"))
        .isEqualTo(
            "class Foo {\n"
                + "  void f() {\n"
                + "    int x = 0; // comment\n"
                + "    return;\n"
                + "  }\n"
                + "}\n");
  }
}
