// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.util;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertThrows;

import com.google.common.base.Strings;
import com.google.devtools.build.lib.util.SimpleLogHandler.HandlerQuerier;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Date;
import java.util.Optional;
import java.util.TimeZone;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
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 the {@link SimpleLogHandler} class. */
@RunWith(JUnit4.class)
public final class SimpleLogHandlerTest {

  @Rule public TemporaryFolder tmp = new TemporaryFolder();

  @Test
  public void testPrefix() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello_world_%u%h%%_")
            .build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.
    assertThat(handler.getCurrentLogFilePath().get().toString())
        .startsWith(tmp.getRoot() + File.separator + "hello_world_%u%h%%_");
  }

  @Test
  public void testPatternVariables() throws Exception {
    String username = System.getProperty("user.name");
    if (Strings.isNullOrEmpty(username)) {
      username = "unknown_user";
    }
    String hostname = SimpleLogHandler.getLocalHostnameFirstComponent();

    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello_")
            .setPattern("world_%u%%%h_")
            .build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.
    assertThat(handler.getCurrentLogFilePath().get().toString())
        .startsWith(
            tmp.getRoot() + File.separator + "hello_world_" + username + "%" + hostname + "_");
  }

  @Test
  public void testPatternInvalidVariable() throws Exception {
    assertThrows(
        IllegalArgumentException.class,
        () -> SimpleLogHandler.builder().setPattern("hello_%t").build());
  }

  @Test
  public void testExtensionDefaults() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder().setPrefix(tmp.getRoot() + File.separator + "hello").build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.
    assertThat(handler.getCurrentLogFilePath().get().toString())
        .endsWith("." + SimpleLogHandler.getPidString());
  }

  @Test
  public void testExtensionSetter() throws Exception {
    SimpleLogHandler handler1 =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setExtension("xyz")
            .build();
    handler1.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.
    assertThat(handler1.getCurrentLogFilePath().get().toString()).endsWith(".xyz");
  }

  private static final class FakeClock extends Clock {
    private Instant now;
    private final ZoneId zone;

    FakeClock(Instant now, ZoneId zone) {
      this.now = now;
      this.zone = zone;
    }

    void set(Instant now) {
      this.now = now;
    }

    @Override
    public Instant instant() {
      return now;
    }

    @Override
    public ZoneId getZone() {
      return zone;
    }

    @Override
    public Clock withZone(ZoneId zone) {
      return new FakeClock(this.now, zone);
    }
  }

  @Test
  public void testTimestamp() throws Exception {
    Instant instant = Instant.parse("2015-09-01T15:17:54Z");
    FakeClock clock = new FakeClock(instant, ZoneOffset.UTC);
    SimpleDateFormat dateFormat = new SimpleDateFormat(SimpleLogHandler.DEFAULT_TIMESTAMP_FORMAT);
    dateFormat.setTimeZone(TimeZone.getTimeZone(ZoneOffset.UTC));
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setClockForTesting(clock)
            .build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.

    assertThat(dateFormat.format(Date.from(instant))).isEqualTo("20150901-151754.");
    assertThat(handler.getCurrentLogFilePath().get().toString()).contains("20150901-151754.");
  }

  private static final class TrivialFormatter extends Formatter {
    @Override
    public String format(LogRecord rec) {
      return formatMessage(rec) + "\n";
    }
  }

  @Test
  public void testPublish() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setFormatter(new TrivialFormatter())
            .build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.
    Path logPath = handler.getCurrentLogFilePath().get();
    handler.close();

    assertThat(new String(Files.readAllBytes(logPath), UTF_8)).isEqualTo("Hello world\n");
  }

  @Test
  public void testSymbolicLinkDefaults() throws Exception {
    Path symlinkPath = Paths.get(tmp.getRoot().toString(), "hello");
    Files.createFile(symlinkPath);

    // On non-Windows platforms, expect to delete the file at symlinkPath and replace with a symlink
    // to the log.
    SimpleLogHandler handler = SimpleLogHandler.builder().setPrefix(symlinkPath.toString()).build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.

    if (OS.getCurrent() == OS.WINDOWS) {
      // On Windows, by default, only administrator accounts can create symbolic links.
      assertThat(handler.getSymbolicLinkPath()).isEmpty();
    } else {
      assertThat(handler.getSymbolicLinkPath()).isPresent();
      assertThat(handler.getSymbolicLinkPath().get().toString()).isEqualTo(symlinkPath.toString());
      assertThat(Files.isSymbolicLink(handler.getSymbolicLinkPath().get())).isTrue();
      assertThat(Files.readSymbolicLink(handler.getSymbolicLinkPath().get()).toString())
          .isEqualTo(handler.getCurrentLogFilePath().get().getFileName().toString());
    }
  }

  @Test
  public void testSymbolicLinkSetter() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setSymlinkName("bye")
            .build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.

    if (OS.getCurrent() == OS.WINDOWS) {
      // On Windows, by default, only administrator accounts can create symbolic links.
      assertThat(handler.getSymbolicLinkPath()).isEmpty();
    } else {
      assertThat(handler.getSymbolicLinkPath()).isPresent();
      assertThat(handler.getSymbolicLinkPath().get().toString())
          .isEqualTo(tmp.getRoot() + File.separator + "bye");
      assertThat(Files.isSymbolicLink(handler.getSymbolicLinkPath().get())).isTrue();
      assertThat(Files.readSymbolicLink(handler.getSymbolicLinkPath().get()).toString())
          .isEqualTo(handler.getCurrentLogFilePath().get().getFileName().toString());
    }
  }

  @Test
  public void testSymlinkEnabling() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setSymlinkName("bye")
            .setCreateSymlink(true)
            .build();
    assertThat(handler.getSymbolicLinkPath()).isPresent();
  }

  @Test
  public void testSymlinkDisabling() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setSymlinkName("bye")
            .setCreateSymlink(false)
            .build();
    assertThat(handler.getSymbolicLinkPath()).isEmpty();
  }

  @Test
  public void testSymbolicLinkInvalidPath() throws Exception {
    // "bye/bye" is invalid as a symlink path - it's not at the top level of log directory.
    SimpleLogHandler.Builder builder =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setSymlinkName("bye" + File.separator + "bye")
            .setCreateSymlink(true);
    assertThrows(IllegalArgumentException.class, () -> builder.build());
  }

  @Test
  public void testSymbolicLinkInitiallyInvalidReplaced() throws Exception {
    if (OS.getCurrent() == OS.WINDOWS) {
      // On Windows, by default, only administrator accounts can create symbolic links.
      return;
    }
    Path symlinkPath = Paths.get(tmp.getRoot().toString(), "hello");
    Files.createSymbolicLink(symlinkPath, Paths.get("no-such-file"));

    // Expected to delete the (invalid) symlink and replace with a symlink to the log
    SimpleLogHandler handler =
        SimpleLogHandler.builder().setPrefix(symlinkPath.toString()).build();
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // To open the log file.

    assertThat(handler.getSymbolicLinkPath().get().toString()).isEqualTo(symlinkPath.toString());
    assertThat(Files.isSymbolicLink(handler.getSymbolicLinkPath().get())).isTrue();
    assertThat(Files.readSymbolicLink(handler.getSymbolicLinkPath().get()).toString())
        .isEqualTo(handler.getCurrentLogFilePath().get().getFileName().toString());
  }

  @Test
  public void testLogLevelEqualPublished() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "info")
            .setLogLevel(Level.INFO)
            .build();
    handler.publish(new LogRecord(Level.INFO, "Hello"));
    Optional<Path> logPath = handler.getCurrentLogFilePath();
    handler.close();

    assertThat(Files.size(logPath.get())).isGreaterThan(0L);
  }

  @Test
  public void testLogLevelHigherPublished() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "info")
            .setLogLevel(Level.INFO)
            .build();
    handler.publish(new LogRecord(Level.WARNING, "Hello"));
    Optional<Path> logPath = handler.getCurrentLogFilePath();
    handler.close();

    assertThat(Files.size(logPath.get())).isGreaterThan(0L);
  }

  @Test
  public void testLogLevelLowerNotPublished() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "info")
            .setLogLevel(Level.INFO)
            .build();
    handler.publish(new LogRecord(Level.FINE, "Hello"));
    Optional<Path> logPath = handler.getCurrentLogFilePath();
    handler.close();

    assertThat(logPath.isPresent()).isFalse();
  }

  @Test
  public void testLogLevelDefaultAllPublished() throws Exception {
    SimpleLogHandler handler =
        SimpleLogHandler.builder().setPrefix(tmp.getRoot() + File.separator + "all").build();
    handler.publish(new LogRecord(Level.FINEST, "Hello"));
    Optional<Path> logPath = handler.getCurrentLogFilePath();
    handler.close();

    assertThat(Files.size(logPath.get())).isGreaterThan(0L);
  }

  @Test
  public void testRotateLimitBytes() throws Exception {
    FakeClock clock = new FakeClock(Instant.parse("2018-01-01T12:00:00Z"), ZoneOffset.UTC);
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "limits")
            .setFormatter(new TrivialFormatter())
            .setRotateLimitBytes(16)
            .setClockForTesting(clock)
            .build();
    Optional<Path> symlinkPath = handler.getSymbolicLinkPath();
    handler.publish(new LogRecord(Level.SEVERE, "1234567" /* 8 bytes including "\n" */));
    Path firstLogPath = handler.getCurrentLogFilePath().get();
    clock.set(Instant.parse("2018-01-01T12:00:01Z")); // Ensure the next file has a different name.
    handler.publish(new LogRecord(Level.SEVERE, "1234567" /* 8 bytes including "\n" */));
    Path secondLogPath = handler.getCurrentLogFilePath().get();
    handler.publish(new LogRecord(Level.SEVERE, "1234567" /* 8 bytes including "\n" */));
    handler.close();

    if (symlinkPath.isPresent()) {
      // The symlink path is expected to be present on non-Windows platforms; see tests above.
      assertThat(Files.isSymbolicLink(symlinkPath.get())).isTrue();
      assertThat(Files.readSymbolicLink(symlinkPath.get()).toString())
          .isEqualTo(secondLogPath.getFileName().toString());
    }
    assertThat(Files.size(firstLogPath)).isEqualTo(16L /* including two "\n" */);
    assertThat(Files.size(secondLogPath)).isEqualTo(8L /* including "\n" */);
    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(tmp.getRoot().toPath())) {
      assertThat(dirStream).hasSize(3);
    }
  }

  private Path newFileWithContent(String name, String content) throws IOException {
    File file = tmp.newFile(name);
    try (OutputStreamWriter writer =
        new OutputStreamWriter(new FileOutputStream(file.getPath()), UTF_8)) {
      writer.write(content);
    }
    return file.toPath();
  }

  private Path newFileOfSize(String name, int size) throws IOException {
    char[] buf = new char[size];
    Arrays.fill(buf, '\n');
    return newFileWithContent(name, new String(buf));
  }

  @Test
  public void testOpenInAppendMode() throws Exception {
    Path logPath = newFileWithContent("hello.20150901-151754.log", "Previous logs\n");
    Instant instant = Instant.parse("2015-09-01T15:17:54Z");
    FakeClock clock = new FakeClock(instant, ZoneOffset.UTC);
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setPattern(".")
            .setExtension("log")
            .setFormatter(new TrivialFormatter())
            .setClockForTesting(clock)
            .build();
    handler.publish(new LogRecord(Level.SEVERE, "New logs"));
    assertThat(handler.getCurrentLogFilePath().get().toString()).isEqualTo(logPath.toString());
    handler.close();
    try (BufferedReader logReader =
        new BufferedReader(new InputStreamReader(new FileInputStream(logPath.toFile()), UTF_8))) {
      assertThat(logReader.readLine()).isEqualTo("Previous logs");
      assertThat(logReader.readLine()).isEqualTo("New logs");
    }
  }

  @Test
  public void testTotalLimit() throws Exception {
    String username = System.getProperty("user.name");
    if (Strings.isNullOrEmpty(username)) {
      username = "unknown_user";
    }
    String hostname = SimpleLogHandler.getLocalHostnameFirstComponent();
    String baseFilename = "hello." + hostname + "." + username + ".log.java.";
    Path nonLog = newFileOfSize("non_log", 16);
    Path missingDate = newFileOfSize(baseFilename + ".123", 16);
    Path invalidExtension = newFileOfSize(baseFilename + "19900101-120000.invalid", 16);
    Path oldDeleted1 = newFileOfSize(baseFilename + "19900101-120000.123", 16);
    Path oldDeleted2 = newFileOfSize(baseFilename + "19950101-120000.123", 16);
    Path keptThenDeleted = newFileOfSize(baseFilename + "19990101-120000.123", 16);
    Path kept = newFileOfSize(baseFilename + "19990606-060000.123", 16);

    FakeClock clock = new FakeClock(Instant.parse("2018-01-01T12:00:00Z"), ZoneOffset.UTC);
    SimpleLogHandler handler =
        SimpleLogHandler.builder()
            .setPrefix(tmp.getRoot() + File.separator + "hello")
            .setPattern(".%h.%u.log.java.")
            .setFormatter(new TrivialFormatter())
            .setRotateLimitBytes(16)
            .setTotalLimitBytes(40)
            .setClockForTesting(clock)
            .build();
    // Print 8 bytes into the log file. Opening the log file triggers deletion of old logs.
    handler.publish(new LogRecord(Level.SEVERE, "1234567" /* 8 bytes including "\n" */));

    // We expect handler to delete all but 32 = 40 - 8 bytes worth of old log files.
    assertThat(Files.exists(nonLog)).isTrue();
    assertThat(Files.exists(missingDate)).isTrue();
    assertThat(Files.exists(invalidExtension)).isTrue();
    assertThat(Files.exists(oldDeleted1)).isFalse();
    assertThat(Files.exists(oldDeleted2)).isFalse();
    assertThat(Files.exists(keptThenDeleted)).isTrue();
    assertThat(Files.exists(kept)).isTrue();

    handler.publish(new LogRecord(Level.SEVERE, "1234567" /* 8 bytes including "\n" */));
    Path currentLogPath = handler.getCurrentLogFilePath().get();
    handler.close();

    // We expect another old log file to be deleted after rotation.
    assertThat(Files.exists(keptThenDeleted)).isFalse();
    assertThat(Files.exists(kept)).isTrue();
    assertThat(Files.exists(currentLogPath)).isTrue();
  }

  @Test
  public void getLoggerFilePath_onSimpleLogHandler_withFile_returnsPath() throws Exception {
    HandlerQuerier handlerQuerier = new HandlerQuerier();
    SimpleLogHandler handler =
        SimpleLogHandler.builder().setPrefix(tmp.getRoot() + File.separator + "hello").build();
    Logger logger = Logger.getAnonymousLogger();
    logger.addHandler(handler);
    handler.publish(new LogRecord(Level.SEVERE, "Hello world")); // Ensure log file is opened.

    Optional<Path> retrievedLogPath = handlerQuerier.getLoggerFilePath(logger);

    assertThat(retrievedLogPath).isPresent();
    assertThat(retrievedLogPath.get().toString())
        .startsWith(tmp.getRoot() + File.separator + "hello");

    handler.close();
  }

  @Test
  public void getLoggerFilePath_onSimpleLogHandler_withoutFile_returnsEmpty() throws Exception {
    HandlerQuerier handlerQuerier = new HandlerQuerier();
    SimpleLogHandler handler =
        SimpleLogHandler.builder().setPrefix(tmp.getRoot() + File.separator + "hello").build();
    Logger logger = Logger.getAnonymousLogger();
    logger.addHandler(handler);

    assertThat(handlerQuerier.getLoggerFilePath(logger)).isEmpty();
  }

  @Test
  public void getLoggerFilePath_onUnsupportedLogHandler_fails() throws Exception {
    HandlerQuerier handlerQuerier = new HandlerQuerier();
    FileHandler unsupportedHandler = new FileHandler(tmp.getRoot() + File.separator + "hello");
    Logger logger = Logger.getAnonymousLogger();
    logger.addHandler(unsupportedHandler);

    assertThrows(IllegalArgumentException.class, () -> handlerQuerier.getLoggerFilePath(logger));

    unsupportedHandler.close();
  }

  @Test
  public void getLoggerFilePath_onMissingLogHandler_fails() throws Exception {
    HandlerQuerier handlerQuerier = new HandlerQuerier();
    Logger logger = Logger.getAnonymousLogger();

    assertThrows(IllegalArgumentException.class, () -> handlerQuerier.getLoggerFilePath(logger));
  }
}
