/*
 * 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 java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Joiner;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for error reporting. */
@RunWith(JUnit4.class)
public class DiagnosticTest {
  @Rule public TemporaryFolder testFolder = new TemporaryFolder();

  private Locale backupLocale;

  @Before
  public void setUpLocale() throws Exception {
    backupLocale = Locale.getDefault();
    Locale.setDefault(Locale.ROOT);
  }

  @After
  public void restoreLocale() throws Exception {
    Locale.setDefault(backupLocale);
  }

  @Test
  public void parseError() throws Exception {
    String input =
        Joiner.on('\n')
            .join(
                "public class InvalidSyntax {",
                "  private static NumPrinter {",
                "    public static void print(int n) {",
                "      System.out.printf(\"%d%n\", n);",
                "    }",
                "  }",
                "",
                "  public static void main(String[] args) {",
                "    NumPrinter.print(args.length);",
                "  }",
                "}");

    StringWriter stdout = new StringWriter();
    StringWriter stderr = new StringWriter();
    Main main = new Main(new PrintWriter(stdout, true), new PrintWriter(stderr, true), System.in);

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

    int result = main.format(path.toString());
    assertThat(stdout.toString()).isEmpty();
    assertThat(stderr.toString()).contains("InvalidSyntax.java:2:29: error: <identifier> expected");
    assertThat(result).isEqualTo(1);
  }

  @Test
  public void lexError() throws Exception {
    String input = "\\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu00not-actually-a-unicode-escape-sequence";

    StringWriter stdout = new StringWriter();
    StringWriter stderr = new StringWriter();
    Main main = new Main(new PrintWriter(stdout, true), new PrintWriter(stderr, true), System.in);

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

    int result = main.format(path.toString());
    assertThat(stdout.toString()).isEmpty();
    assertThat(stderr.toString())
        .contains("InvalidSyntax.java:1:35: error: illegal unicode escape");
    assertThat(result).isEqualTo(1);
  }

  @Test
  public void oneFileParseError() throws Exception {
    String one = "class One {\n";
    String two = "class Two {}\n";

    StringWriter stdout = new StringWriter();
    StringWriter stderr = new StringWriter();
    Main main = new Main(new PrintWriter(stdout, true), new PrintWriter(stderr, true), System.in);

    Path tmpdir = testFolder.newFolder().toPath();
    Path pathOne = tmpdir.resolve("One.java");
    Files.write(pathOne, one.getBytes(UTF_8));

    Path pathTwo = tmpdir.resolve("Two.java");
    Files.write(pathTwo, two.getBytes(UTF_8));

    int result = main.format(pathOne.toString(), pathTwo.toString());
    assertThat(stdout.toString()).isEqualTo(two);
    assertThat(stderr.toString()).contains("One.java:1:13: error: reached end of file");
    assertThat(result).isEqualTo(1);
  }

  @Test
  public void oneFileParseErrorReplace() throws Exception {
    String one = "class One {}}\n";
    String two = "class Two {\n}\n";

    StringWriter stdout = new StringWriter();
    StringWriter stderr = new StringWriter();
    Main main = new Main(new PrintWriter(stdout, true), new PrintWriter(stderr, true), System.in);

    Path tmpdir = testFolder.newFolder().toPath();
    Path pathOne = tmpdir.resolve("One.java");
    Files.write(pathOne, one.getBytes(UTF_8));

    Path pathTwo = tmpdir.resolve("Two.java");
    Files.write(pathTwo, two.getBytes(UTF_8));

    int result = main.format("-i", pathOne.toString(), pathTwo.toString());
    assertThat(stdout.toString()).isEmpty();
    assertThat(stderr.toString()).contains("One.java:1:14: error: class, interface");
    assertThat(result).isEqualTo(1);
    // don't edit files with parse errors
    assertThat(Files.readAllLines(pathOne, UTF_8)).containsExactly("class One {}}");
    assertThat(Files.readAllLines(pathTwo, UTF_8)).containsExactly("class Two {}");
  }

  @Test
  public void parseError2() throws FormatterException, IOException, UsageException {
    String input = "class Foo { void f() {\n g() } }";

    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 = {path.toString()};
    int exitCode = main.format(args);

    assertThat(exitCode).isEqualTo(1);
    assertThat(err.toString()).contains("A.java:2:6: error: ';' expected");
  }

  @Test
  public void parseErrorStdin() throws FormatterException, IOException, UsageException {
    String input = "class Foo { void f() {\n g() } }";

    InputStream inStream = new ByteArrayInputStream(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), inStream);
    String[] args = {"-"};
    int exitCode = main.format(args);

    assertThat(exitCode).isEqualTo(1);
    assertThat(err.toString()).contains("<stdin>:2:6: error: ';' expected");
  }

  @Test
  public void lexError2() throws FormatterException, IOException, UsageException {
    String input = "class Foo { void f() {\n g('foo'); } }";

    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 = {path.toString()};
    int exitCode = main.format(args);

    assertThat(exitCode).isEqualTo(1);
    assertThat(err.toString()).contains("A.java:2:5: error: unclosed character literal");
  }

  @Test
  public void lexErrorStdin() throws FormatterException, IOException, UsageException {
    String input = "class Foo { void f() {\n g('foo'); } }";
    InputStream inStream = new ByteArrayInputStream(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), inStream);
    String[] args = {"-"};
    int exitCode = main.format(args);

    assertThat(exitCode).isEqualTo(1);
    assertThat(err.toString()).contains("<stdin>:2:5: error: unclosed character literal");
  }
}
