/*
 * Copyright 2018 The Error Prone Authors.
 *
 * 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.errorprone.bugpatterns.time;

import com.google.errorprone.BugCheckerRefactoringTestHelper;
import com.google.errorprone.CompilationTestHelper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link JavaTimeDefaultTimeZone}. */
@RunWith(JUnit4.class)
public class JavaTimeDefaultTimeZoneTest {
  private final CompilationTestHelper helper =
      CompilationTestHelper.newInstance(JavaTimeDefaultTimeZone.class, getClass())
          .expectErrorMessage("REPLACEME", s -> s.contains("systemDefault()"));

  @Test
  public void clock() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.Clock;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  Clock clock = Clock.systemDefaultZone();",
            "  Clock clockWithZone = Clock.system(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void staticImportOfStaticMethod() {
    BugCheckerRefactoringTestHelper.newInstance(
            JavaTimeDefaultTimeZone.class, JavaTimeDefaultTimeZoneTest.class)
        .addInputLines(
            "in/TestClass.java",
            "import static java.time.LocalDate.now;",
            "",
            "import java.time.LocalDate;",
            "public class TestClass {",
            "  LocalDate date = now();",
            "}")
        .addOutputLines(
            "out/TestClass.java",
            "import static java.time.LocalDate.now;",
            "import java.time.LocalDate;",
            "import java.time.ZoneId;",
            "public class TestClass {",
            "  LocalDate date = now(ZoneId.systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void localDate() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.LocalDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  LocalDate now = LocalDate.now();",
            "  LocalDate nowWithZone = LocalDate.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void localTime() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.LocalTime;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  LocalTime now = LocalTime.now();",
            "  LocalTime nowWithZone = LocalTime.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void localDateTime() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.LocalDateTime;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  LocalDateTime now = LocalDateTime.now();",
            "  LocalDateTime nowWithZone = LocalDateTime.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void monthDay() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.MonthDay;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  MonthDay now = MonthDay.now();",
            "  MonthDay nowWithZone = MonthDay.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void offsetDateTime() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.OffsetDateTime;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  OffsetDateTime now = OffsetDateTime.now();",
            "  OffsetDateTime nowWithZone = OffsetDateTime.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void offsetTime() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.OffsetTime;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  OffsetTime now = OffsetTime.now();",
            "  OffsetTime nowWithZone = OffsetTime.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void year() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.Year;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  Year now = Year.now();",
            "  Year nowWithZone = Year.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void yearMonth() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.YearMonth;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  YearMonth now = YearMonth.now();",
            "  YearMonth nowWithZone = YearMonth.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void zonedDateTime() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.ZonedDateTime;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  ZonedDateTime now = ZonedDateTime.now();",
            "  ZonedDateTime nowWithZone = ZonedDateTime.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void japaneseDate() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.JapaneseDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  JapaneseDate now = JapaneseDate.now();",
            "  JapaneseDate nowWithZone = JapaneseDate.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void minguoDate() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.MinguoDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  MinguoDate now = MinguoDate.now();",
            "  MinguoDate nowWithZone = MinguoDate.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void hijrahDate() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.HijrahDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  HijrahDate now = HijrahDate.now();",
            "  HijrahDate nowWithZone = HijrahDate.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void thaiBuddhistDate() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.ThaiBuddhistDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  ThaiBuddhistDate now = ThaiBuddhistDate.now();",
            "  ThaiBuddhistDate nowWithZone = ThaiBuddhistDate.now(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void chronology() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.Chronology;",
            "import java.time.chrono.ChronoLocalDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  ChronoLocalDate now = Chronology.of(\"ISO\").dateNow();",
            "  ChronoLocalDate nowWithZone = Chronology.of(\"ISO\").dateNow(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void hijrahChronology() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.HijrahChronology;",
            "import java.time.chrono.HijrahDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  HijrahDate now = HijrahChronology.INSTANCE.dateNow();",
            "  HijrahDate nowWithZone = HijrahChronology.INSTANCE.dateNow(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void isoChronology() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.LocalDate;",
            "import java.time.chrono.IsoChronology;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  LocalDate now = IsoChronology.INSTANCE.dateNow();",
            "  LocalDate nowWithZone = IsoChronology.INSTANCE.dateNow(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void japaneseChronology() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.JapaneseChronology;",
            "import java.time.chrono.JapaneseDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  JapaneseDate now = JapaneseChronology.INSTANCE.dateNow();",
            "  JapaneseDate nowWithZone = JapaneseChronology.INSTANCE.dateNow(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void minguoChronology() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.MinguoChronology;",
            "import java.time.chrono.MinguoDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  MinguoDate now = MinguoChronology.INSTANCE.dateNow();",
            "  MinguoDate nowWithZone = MinguoChronology.INSTANCE.dateNow(systemDefault());",
            "}")
        .doTest();
  }

  @Test
  public void thaiBuddhistChronology() {
    helper
        .addSourceLines(
            "TestClass.java",
            "import static java.time.ZoneId.systemDefault;",
            "import java.time.chrono.ThaiBuddhistChronology;",
            "import java.time.chrono.ThaiBuddhistDate;",
            "public class TestClass {",
            "  // BUG: Diagnostic matches: REPLACEME",
            "  ThaiBuddhistDate now = ThaiBuddhistChronology.INSTANCE.dateNow();",
            "  ThaiBuddhistDate nowWithZone = "
                + "ThaiBuddhistChronology.INSTANCE.dateNow(systemDefault());",
            "}")
        .doTest();
  }
}
