// 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.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.io.CountingOutputStream;
import com.google.common.net.InetAddresses;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.management.ManagementFactory;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Date;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.TimeZone;
import java.util.function.Function;
import java.util.logging.ErrorManager;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;

/**
 * A simple file-based logging handler that provides an API for getting the current log file and
 * (optionally) in addition creates a short symlink to the current log file.
 *
 * <p>The log file path is concatenated from 4 elements: the prefix (a fixed string, typically a
 * directory); the pattern (allowing some % variable substitutions); the timestamp; and the
 * extension.
 *
 * <p>The handler can be configured from the JVM command line: <code>
 *   -Djava.util.logging.config.file=/foo/bar/javalog.properties
 * </code> where the javalog.properties file might contain something like <code>
 *    handlers=com.google.devtools.build.lib.util.SimpleLogHandler
 *    com.google.devtools.build.lib.util.SimpleLogHandler.level=INFO
 *    com.google.devtools.build.lib.util.SimpleLogHandler.prefix=/foo/bar/logs/java.log
 *    com.google.devtools.build.lib.util.SimpleLogHandler.rotate_limit_bytes=1048576
 *    com.google.devtools.build.lib.util.SimpleLogHandler.total_limit_bytes=10485760
 *    com.google.devtools.build.lib.util.SimpleLogHandler.formatter=com.google.devtools.build.lib.util.SingleLineFormatter
 * </code>
 *
 * <p>The handler is thread-safe. IO operations ({@link #publish}, {@link #flush}, {@link #close})
 * and {@link #getCurrentLogFilePath} block other access to the handler until completed.
 */
public final class SimpleLogHandler extends Handler {
  /** Max number of bytes to write before rotating the log. */
  private final int rotateLimitBytes;
  /** Max number of bytes in all logs to keep before deleting oldest ones. */
  private final int totalLimitBytes;
  /** Log file extension; the current process ID by default. */
  private final String extension;
  /** True if the log file extension is not the process ID. */
  private final boolean isStaticExtension;
  /**
   * Absolute path to symbolic link to current log file, or {@code Optional#empty()} if the link
   * should not be created.
   */
  private final Optional<Path> symlinkPath;
  /** Absolute path to common base name of log files. */
  @VisibleForTesting final Path baseFilePath;
  /** Log file currently in use. */
  @GuardedBy("this")
  private final Output output = new Output();

  private static final String DEFAULT_PREFIX_STRING = "java.log";
  private static final String DEFAULT_BASE_FILE_NAME_PATTERN = ".%h.%u.log.java.";
  /** Source for timestamps in filenames; non-static for testing. */
  private final Clock clock;

  @VisibleForTesting static final String DEFAULT_TIMESTAMP_FORMAT = "yyyyMMdd-HHmmss.";
  /**
   * Timestamp format for log filenames; non-static because {@link SimpleDateFormat} is not
   * thread-safe.
   */
  @GuardedBy("this")
  private final SimpleDateFormat timestampFormat = new SimpleDateFormat(DEFAULT_TIMESTAMP_FORMAT);

  /**
   * A {@link} LogHandlerQuerier for working with {@code SimpleLogHandler} instances.
   *
   * <p>This querier is intended for situations where the logging handler is configured on the JVM
   * command line to be {@link SimpleLogHandler}, but where the code which needs to query the
   * handler does not know the handler's class or cannot import it. The command line then should in
   * addition specify {@code
   * -Dcom.google.devtools.build.lib.util.LogHandlerQuerier.class=com.google.devtools.build.lib.util.SimpleLogHandler$HandlerQuerier}
   * and an instance of {@link SimpleLogHandler.HandlerQuerier} class can then be obtained from
   * {@code LogHandlerQuerier.getInstance()}.
   */
  public static final class HandlerQuerier extends LogHandlerQuerier {
    @Override
    protected boolean canQuery(Handler handler) {
      return handler instanceof SimpleLogHandler;
    }

    @Override
    protected Optional<Path> getLogHandlerFilePath(Handler handler) {
      return ((SimpleLogHandler) handler).getCurrentLogFilePath();
    }
  }

  /** Creates a new {@link Builder}. */
  public static Builder builder() {
    return new Builder();
  }

  /**
   * Builder class for {@link SimpleLogHandler}.
   *
   * <p>All setters are optional; if unset, values from the JVM logging configuration or (if those
   * too are unset) reasonable fallback values will be used. See individual setter documentation.
   */
  public static final class Builder {
    private String prefix;
    private String pattern;
    private String extension;
    private String symlinkName;
    private Boolean createSymlink;
    private Integer rotateLimitBytes;
    private Integer totalLimitBytes;
    private Level logLevel;
    private Formatter formatter;
    private Clock clock;

    public Builder setPrefix(String prefix) {
      this.prefix = prefix;
      return this;
    }

    /**
     * Sets the pattern for the log file name. The pattern may contain the following variables:
     *
     * <ul>
     *   <li><code>%u</code> will be expanded to the username
     *   <li><code>%h</code> will be expanded to the hostname
     *   <li><code>%%</code> will be expanded to %
     * </ul>
     *
     * <p>The log file name will be constructed by appending the expanded pattern to the prefix and
     * then by appending a timestamp and the extension.
     *
     * <p>If unset, the value of "pattern" from the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, {@link #DEFAULT_BASE_FILE_NAME_PATTERN}
     * will be used.
     *
     * @param pattern the pattern string, possibly containing <code>%u</code>, <code>%h</code>,
     *     <code>%%</code> variables as above
     * @return this {@code Builder} object
     */
    public Builder setPattern(String pattern) {
      this.pattern = pattern;
      return this;
    }

    /**
     * Sets the log file extension.
     *
     * <p>If unset, the value of "extension" from the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, the process ID will be used.
     *
     * @param extension log file extension
     * @return this {@code Builder} object
     */
    public Builder setExtension(String extension) {
      this.extension = extension;
      return this;
    }

    /**
     * Sets the log file symlink filename.
     *
     * <p>If unset, the value of "symlink" from the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, the prefix will be used.
     *
     * @param symlink either symlink filename without a directory part, or an absolute path whose
     *     directory part matches the prefix
     * @return this {@code Builder} object
     */
    public Builder setSymlinkName(String symlinkName) {
      this.symlinkName = symlinkName;
      return this;
    }

    /**
     * Sets whether symlinks to the log file should be created.
     *
     * <p>If unset, the value of "create_symlink" from the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, the default behavior will depend on the
     * platform: false on Windows (because by default, only administrator accounts can create
     * symbolic links there) and true on other platforms.
     *
     * @return this {@code Builder} object
     */
    public Builder setCreateSymlink(boolean createSymlink) {
      this.createSymlink = Boolean.valueOf(createSymlink);
      return this;
    }

    /**
     * Sets the log file size limit; if unset or 0, log size is unlimited.
     *
     * <p>If unset, the value of "rotate_limit_bytes" from the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, the log fie size is unlimited.
     *
     * @param rotateLimitBytes maximum log file size in bytes; must be >= 0; 0 means unlimited
     * @return this {@code Builder} object
     */
    public Builder setRotateLimitBytes(int rotateLimitBytes) {
      this.rotateLimitBytes = Integer.valueOf(rotateLimitBytes);
      return this;
    }

    /**
     * Sets the total rotateLimitBytes for log files.
     *
     * <p>If set, when opening a new handler or rotating a log file, the handler will scan for all
     * log files with names matching the expected prefix, pattern, timestamp format, and extension,
     * and delete the oldest ones to keep the total size under rotateLimitBytes.
     *
     * <p>If unset, the value of "total_limit_bytes" from the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, the total log size is unlimited.
     *
     * @param totalLimitBytes maximum total log file size in bytes; must be >= 0; 0 means unlimited
     * @return this {@code Builder} object
     */
    public Builder setTotalLimitBytes(int totalLimitBytes) {
      this.totalLimitBytes = Integer.valueOf(totalLimitBytes);
      return this;
    }

    /**
     * Sets the minimum level at which to log records.
     *
     * <p>If unset, the level named by the "level" field in the JVM logging configuration for {@link
     * SimpleLogHandler} will be used; and if that's unset, all records are logged.
     *
     * @param logLevel minimum log level
     * @return this {@code Builder} object
     */
    public Builder setLogLevel(Level logLevel) {
      this.logLevel = logLevel;
      return this;
    }

    /**
     * Sets the log formatter.
     *
     * <p>If unset, the class named by the "formatter" field in the JVM logging configuration for
     * {@link SimpleLogHandler} will be used; and if that's unset, {@link SingleLineFormatter} will
     * be used.
     *
     * @param formatter log formatter
     * @return this {@code Builder} object
     */
    public Builder setFormatter(Formatter formatter) {
      this.formatter = formatter;
      return this;
    }

    /**
     * Sets the time source for timestamps in log filenames.
     *
     * <p>Intended for testing. If unset, the system clock in the system timezone will be used.
     *
     * @param clock time source for timestamps
     * @return this {@code Builder} object
     */
    @VisibleForTesting
    Builder setClockForTesting(Clock clock) {
      this.clock = clock;
      return this;
    }

    /** Builds a {@link SimpleLogHandler} instance. */
    public SimpleLogHandler build() {
      return new SimpleLogHandler(
          prefix,
          pattern,
          extension,
          symlinkName,
          createSymlink,
          rotateLimitBytes,
          totalLimitBytes,
          logLevel,
          formatter,
          clock);
    }
  }

  /**
   * Constructs a log handler with all state taken from the JVM logging configuration or (as
   * fallback) the defaults; see {@link SimpleLogHandler.Builder} documentation.
   *
   * @throws IllegalArgumentException if invalid JVM logging configuration values are encountered;
   *     see {@link SimpleLogHandler.Builder} documentation
   */
  public SimpleLogHandler() {
    this(null, null, null, null, null, null, null, null, null, null);
  }

  /**
   * Constructs a log handler, falling back to the JVM logging configuration or (as last fallback)
   * the defaults for those arguments which are null; see {@link SimpleLogHandler.Builder}
   * documentation.
   *
   * @throws IllegalArgumentException if invalid non-null arguments or configured values are
   *     encountered; see {@link SimpleLogHandler.Builder} documentation
   */
  private SimpleLogHandler(
      @Nullable String prefix,
      @Nullable String pattern,
      @Nullable String extension,
      @Nullable String symlinkName,
      @Nullable Boolean createSymlink,
      @Nullable Integer rotateLimitBytes,
      @Nullable Integer totalLimit,
      @Nullable Level logLevel,
      @Nullable Formatter formatter,
      @Nullable Clock clock) {
    this.baseFilePath =
        getBaseFilePath(
            getConfiguredStringProperty(prefix, "prefix", DEFAULT_PREFIX_STRING),
            getConfiguredStringProperty(pattern, "pattern", DEFAULT_BASE_FILE_NAME_PATTERN));

    String configuredSymlinkName =
        getConfiguredStringProperty(
            symlinkName,
            "symlink",
            getConfiguredStringProperty(prefix, "prefix", DEFAULT_PREFIX_STRING));
    boolean configuredCreateSymlink =
        getConfiguredBooleanProperty(
            createSymlink, "create_symlink", OS.getCurrent() != OS.WINDOWS);
    this.symlinkPath =
        configuredCreateSymlink
            ? Optional.of(
                getSymlinkAbsolutePath(this.baseFilePath.getParent(), configuredSymlinkName))
            : Optional.empty();
    this.extension = getConfiguredStringProperty(extension, "extension", getPidString());
    this.isStaticExtension = (getConfiguredStringProperty(extension, "extension", null) != null);
    this.rotateLimitBytes = getConfiguredIntProperty(rotateLimitBytes, "rotate_limit_bytes", 0);
    checkArgument(this.rotateLimitBytes >= 0, "File size limits cannot be negative");
    this.totalLimitBytes = getConfiguredIntProperty(totalLimit, "total_limit_bytes", 0);
    checkArgument(this.totalLimitBytes >= 0, "File size limits cannot be negative");
    setLevel(getConfiguredLevelProperty(logLevel, "level", Level.ALL));
    setFormatter(getConfiguredFormatterProperty(formatter, "formatter", new SingleLineFormatter()));
    if (clock != null) {
      this.clock = clock;
      this.timestampFormat.setTimeZone(TimeZone.getTimeZone(clock.getZone()));
    } else {
      this.clock = Clock.system(ZoneId.systemDefault());
    }
  }

  /**
   * Returns the absolute path of the current log file if a log file is open or {@code
   * Optional#empty()} otherwise.
   *
   * <p>Since the log file is opened lazily, this method is expected to return {@code
   * Optional#empty()} if no record has yet been published.
   */
  public synchronized Optional<Path> getCurrentLogFilePath() {
    return output.isOpen() ? Optional.of(output.getPath()) : Optional.empty();
  }

  /**
   * Returns the expected absolute path for the symbolic link to the current log file, or {@code
   * Optional#empty()} if not used.
   */
  public Optional<Path> getSymbolicLinkPath() {
    return symlinkPath;
  }

  @Override
  public boolean isLoggable(LogRecord record) {
    return record != null && super.isLoggable(record);
  }

  @Override
  public synchronized void publish(LogRecord record) {
    if (!isLoggable(record)) {
      // Silently ignore null or filtered records, matching FileHandler behavior.
      return;
    }

    try {
      String message = getFormatter().format(record);
      openOutputIfNeeded();
      output.write(message);
    } catch (Exception e) {
      reportError(null, e, ErrorManager.WRITE_FAILURE);
      // Failing to log is non-fatal. Continue to try to rotate the log if necessary, which may fix
      // the underlying IO problem with the file.
    }

    try {
      if (rotateLimitBytes > 0) {
        output.closeIfByteCountAtleast(rotateLimitBytes);
        openOutputIfNeeded();
      }
    } catch (IOException e) {
      reportError("Failed to rotate log file", e, ErrorManager.GENERIC_FAILURE);
    }
  }

  @Override
  public synchronized void flush() {
    if (output.isOpen()) {
      try {
        output.flush();
      } catch (IOException e) {
        reportError(null, e, ErrorManager.FLUSH_FAILURE);
      }
    }
  }

  @Override
  public synchronized void close() {
    if (output.isOpen()) {
      try {
        output.write(getFormatter().getTail(this));
      } catch (IOException e) {
        reportError("Failed to write log tail", e, ErrorManager.WRITE_FAILURE);
      }

      try {
        output.close();
      } catch (IOException e) {
        reportError(null, e, ErrorManager.CLOSE_FAILURE);
      }
    }
  }

  /**
   * Checks if a value is null, and if it is, falls back to the JVM logging configuration, and if
   * that too is missing, to a provided fallback value.
   *
   * @param builderValue possibly null value provided by the caller, e.g. from {@link
   *     SimpleLogHandler.Builder}
   * @param configuredName field name in the JVM logging configuration for {@link SimpleLogHandler}
   * @param parse parser for the string value from the JVM logging configuration
   * @param fallbackValue fallback to use if the {@code builderValue} is null and no value is
   *     configured in the JVM logging configuration
   * @param <T> value type
   */
  private static @Nullable <T> T getConfiguredProperty(
      @Nullable T builderValue,
      String configuredName,
      Function<String, T> parse,
      @Nullable T fallbackValue) {
    if (builderValue != null) {
      return builderValue;
    }

    String configuredValue =
        LogManager.getLogManager()
            .getProperty(SimpleLogHandler.class.getName() + "." + configuredName);
    if (configuredValue != null) {
      return parse.apply(configuredValue);
    }
    return fallbackValue;
  }

  /** Matches java.logging.* configuration behavior; configured strings are trimmed. */
  private static String getConfiguredStringProperty(
      String builderValue, String configuredName, String fallbackValue) {
    return getConfiguredProperty(builderValue, configuredName, val -> val.trim(), fallbackValue);
  }

  /**
   * Matches java.logging.* configuration behavior; "true" and "1" are true, "false" and "0" are
   * false.
   *
   * @throws IllegalArgumentException if the configured boolean property cannot be parsed
   */
  private static boolean getConfiguredBooleanProperty(
      Boolean builderValue, String configuredName, boolean fallbackValue) {
    Boolean value =
        getConfiguredProperty(
            builderValue,
            configuredName,
            val -> {
              val = val.trim().toLowerCase();
              if ("true".equals(val) || "1".equals(val)) {
                return true;
              } else if ("false".equals(val) || "0".equals(val)) {
                return false;
              } else if (val.length() == 0) {
                return null;
              }
              throw new IllegalArgumentException("Cannot parse boolean property value");
            },
            null);
    return value != null ? value.booleanValue() : fallbackValue;
  }

  /**
   * Empty configured values are ignored and the fallback is used instead.
   *
   * @throws NumberFormatException if the configured formatter value is non-numeric
   */
  private static int getConfiguredIntProperty(
      Integer builderValue, String configuredName, int fallbackValue) {
    Integer value =
        getConfiguredProperty(
            builderValue,
            configuredName,
            val -> {
              val = val.trim();
              return val.length() > 0 ? Integer.parseInt(val) : null;
            },
            null);
    return value != null ? value.intValue() : fallbackValue;
  }

  /**
   * Empty configured values are ignored and the fallback is used instead.
   *
   * @throws IllegalArgumentException if the configured level name cannot be parsed
   */
  private static Level getConfiguredLevelProperty(
      Level builderValue, String configuredName, Level fallbackValue) {
    Level value =
        getConfiguredProperty(
            builderValue,
            configuredName,
            val -> {
              val = val.trim();
              return val.length() > 0 ? Level.parse(val) : null;
            },
            null);
    return value != null ? value : fallbackValue;
  }

  /**
   * Empty configured values are ignored and the fallback is used instead.
   *
   * @throws IllegalArgumentException if a formatter object cannot be instantiated from the
   *     configured class name
   */
  private static Formatter getConfiguredFormatterProperty(
      Formatter builderValue, String configuredName, Formatter fallbackValue) {
    return getConfiguredProperty(
        builderValue,
        configuredName,
        val -> {
          val = val.trim();
          if (val.length() > 0) {
            try {
              return (Formatter)
                  ClassLoader.getSystemClassLoader()
                      .loadClass(val)
                      .getDeclaredConstructor()
                      .newInstance();
            } catch (ReflectiveOperationException e) {
              throw new IllegalArgumentException(e);
            }
          } else {
            return fallbackValue;
          }
        },
        fallbackValue);
  }

  @VisibleForTesting
  static String getPidString() {
    long pid;
    try {
      // TODO(b/78168359): Replace with ProcessHandle.current().pid() in Java 9
      pid = Long.parseLong(ManagementFactory.getRuntimeMXBean().getName().split("@", -1)[0]);
    } catch (NumberFormatException e) {
      // getRuntimeMXBean().getName() output is implementation-specific, may be unparseable.
      pid = 0;
    }
    return Long.toString(pid);
  }

  @VisibleForTesting
  static String getLocalHostnameFirstComponent() {
    String name = NetUtil.getCachedShortHostName();
    if (!InetAddresses.isInetAddress(name)) {
      // Keep only the first component of the name.
      int firstDot = name.indexOf('.');
      if (firstDot >= 0) {
        name = name.substring(0, firstDot);
      }
    }
    return name.toLowerCase();
  }

  /**
   * Creates the log file absolute base path according to the given pattern.
   *
   * @param prefix non-null string to prepend to the base path
   * @param pattern non-null string which may include the following variables: %h will be expanded
   *     to the hostname; %u will be expanded to the username; %% will be expanded to %
   * @throws IllegalArgumentException if an unknown variable is encountered in the pattern
   */
  private static Path getBaseFilePath(String prefix, String pattern) {
    checkNotNull(prefix, "prefix");
    checkNotNull(pattern, "pattern");

    StringBuilder sb = new StringBuilder(100); // Typical name is < 100 bytes
    boolean inVar = false;
    String username = System.getProperty("user.name");

    if (Strings.isNullOrEmpty(username)) {
      username = "unknown_user";
    }

    sb.append(prefix);

    for (int i = 0; i < pattern.length(); ++i) {
      char c = pattern.charAt(i);
      if (inVar) {
        inVar = false;
        switch (c) {
          case '%':
            sb.append('%');
            break;
          case 'h':
            sb.append(getLocalHostnameFirstComponent());
            break;
          case 'u':
            sb.append(username);
            break;
          default:
            throw new IllegalArgumentException("Unknown variable " + c + " in " + pattern);
        }
      } else {
        if (c == '%') {
          inVar = true;
        } else {
          sb.append(c);
        }
      }
    }

    return new File(sb.toString()).getAbsoluteFile().toPath();
  }

  /**
   * Returns the absolute path for a symlink in the specified directory.
   *
   * @throws IllegalArgumentException if the symlink includes a directory component which doesn't
   *     equal {@code logDir}
   */
  private static Path getSymlinkAbsolutePath(Path logDir, String symlink) {
    checkNotNull(symlink);
    checkArgument(symlink.length() > 0);
    File symlinkFile = new File(symlink);
    if (!symlinkFile.isAbsolute()) {
      symlinkFile = new File(logDir + File.separator + symlink);
    }
    checkArgument(
        symlinkFile.toPath().getParent().equals(logDir),
        "symlink is not a top-level file in logDir");
    return symlinkFile.toPath();
  }

  private static final class Output {
    /** Log file currently in use. */
    private @Nullable File file;
    /** Output stream for {@link #file} which counts the number of bytes written. */
    private @Nullable CountingOutputStream stream;
    /** Writer for {@link #stream}. */
    private @Nullable OutputStreamWriter writer;

    public boolean isOpen() {
      return writer != null;
    }

    /**
     * Opens the specified file in append mode, first closing the current file if needed.
     *
     * @throws IOException if the file could not be opened
     */
    public void open(String path) throws IOException {
      try {
        close();
        file = new File(path);
        stream = new CountingOutputStream(new FileOutputStream(file, true));
        writer = new OutputStreamWriter(stream, UTF_8);
      } catch (IOException e) {
        close();
        throw e;
      }
    }

    /**
     * Returns the currently open file's path.
     *
     * @throws NullPointerException if not open
     */
    public Path getPath() {
      return file.toPath();
    }

    /**
     * Writes the string to the current file in UTF-8 encoding.
     *
     * @throws NullPointerException if not open
     * @throws IOException if an underlying IO operation failed
     */
    public void write(String string) throws IOException {
      writer.write(string);
    }

    /**
     * Flushes the current file.
     *
     * @throws NullPointerException if not open
     * @throws IOException if an underlying IO operation failed
     */
    public void flush() throws IOException {
      writer.flush();
    }

    /**
     * Closes the current file if it is open.
     *
     * @throws IOException if an underlying IO operation failed
     */
    public void close() throws IOException {
      try {
        if (isOpen()) {
          writer.close();
        }
      } finally {
        writer = null;
        stream = null;
        file = null;
      }
    }

    /**
     * Closes the current file unless the number of bytes written to it was under the specified
     * limit.
     *
     * @throws NullPointerException if not open
     * @throws IOException if an underlying IO operation failed
     */
    public void closeIfByteCountAtleast(int limit) throws IOException {
      if (stream.getCount() < limit && stream.getCount() + 8192L >= limit) {
        // The writer and its internal encoder buffer output before writing to the output stream.
        // The default size of the encoder's buffer is 8192 bytes. To count the bytes in the output
        // stream accurately, we have to flush. But flushing unnecessarily harms performance; let's
        // flush only when it matters - per record and within expected buffer size from the limit.
        flush();
      }
      if (stream.getCount() >= limit) {
        close();
      }
    }
  }

  /**
   * Opens a new log file if one is not open, updating the symbolic link and deleting old logs if
   * needed.
   */
  @GuardedBy("this")
  private void openOutputIfNeeded() {
    if (!output.isOpen()) {
      // Ensure the log file's directory exists.
      checkState(baseFilePath.isAbsolute());
      baseFilePath.getParent().toFile().mkdirs();

      try {
        output.open(
            baseFilePath + timestampFormat.format(Date.from(Instant.now(clock))) + extension);
        output.write(getFormatter().getHead(this));
      } catch (IOException e) {
        try {
          output.close();
        } catch (IOException eClose) {
          // Already handling a prior IO failure.
        }
        reportError("Failed to open log file", e, ErrorManager.OPEN_FAILURE);
        return;
      }

      if (totalLimitBytes > 0) {
        deleteOldLogs();
      }

      // Try to create relative symlink from currentLogFile to baseFile, but don't treat a failure
      // as fatal.
      if (symlinkPath.isPresent()) {
        try {
          checkState(symlinkPath.get().getParent().equals(output.getPath().getParent()));
          if (Files.exists(symlinkPath.get(), LinkOption.NOFOLLOW_LINKS)) {
            Files.delete(symlinkPath.get());
          }
          Files.createSymbolicLink(symlinkPath.get(), output.getPath().getFileName());
        } catch (IOException e) {
          reportError(
              "Failed to create symbolic link to log file", e, ErrorManager.GENERIC_FAILURE);
        }
      }
    }
  }

  /**
   * Parses the absolute path of a logfile (e.g from a previous run of the program) and extracts the
   * timestamp.
   *
   * @throws ParseException if the path does not match the expected prefix, resolved pattern,
   *     timestamp format, or extension
   */
  @GuardedBy("this")
  private Date parseLogFileTimestamp(Path path) throws ParseException {
    String pathString = path.toString();
    if (!pathString.startsWith(baseFilePath.toString())) {
      throw new ParseException("Wrong prefix or pattern", 0);
    }
    ParsePosition parsePosition = new ParsePosition(baseFilePath.toString().length());
    Date timestamp = timestampFormat.parse(pathString, parsePosition);
    if (timestamp == null) {
      throw new ParseException("Wrong timestamp format", parsePosition.getErrorIndex());
    }
    if (isStaticExtension) {
      if (!pathString.substring(parsePosition.getIndex()).equals(extension)) {
        throw new ParseException("Wrong file extension", parsePosition.getIndex());
      }
    } else {
      try {
        Long.parseLong(pathString.substring(parsePosition.getIndex()));
      } catch (NumberFormatException e) {
        throw new ParseException("File extension is not a numeric PID", parsePosition.getIndex());
      }
    }
    return timestamp;
  }

  /**
   * File path ordered by timestamp.
   */
  private static final class PathByTimestamp implements Comparable<PathByTimestamp> {
    private final Path path;
    private final Date timestamp;
    private final long size;

    PathByTimestamp(Path path, Date timestamp, long size) {
      this.path = path;
      this.timestamp = timestamp;
      this.size = size;
    }

    Path getPath() {
      return path;
    }

    long getSize() {
      return size;
    }

    @Override
    public int compareTo(PathByTimestamp rhs) {
      return this.timestamp.compareTo(rhs.timestamp);
    }
  }

  /**
   * Deletes the oldest log files matching the expected prefix, pattern, timestamp format, and
   * extension, to keep the total size under {@link #totalLimitBytes} (if set to non-0).
   *
   * <p>Each log file's timestamp is determined only from the filename. The current log file will
   * not be deleted.
   */
  @GuardedBy("this")
  private void deleteOldLogs() {
    checkState(baseFilePath.isAbsolute());
    PriorityQueue<PathByTimestamp> queue = new PriorityQueue<>();
    long totalSize = 0;
    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(baseFilePath.getParent())) {
      for (Path path : dirStream) {
        try {
          Date timestamp = parseLogFileTimestamp(path);
          long size = Files.size(path);
          totalSize += size;
          if (!output.getPath().equals(path)) {
            queue.add(new PathByTimestamp(path, timestamp, size));
          }
        } catch (ParseException e) {
          // Ignore files which don't look like our logs.
        }
      }

      if (totalLimitBytes > 0) {
        while (totalSize > totalLimitBytes && !queue.isEmpty()) {
          PathByTimestamp entry = queue.poll();
          Files.delete(entry.getPath());
          totalSize -= entry.getSize();
        }
      }
    } catch (IOException e) {
      reportError("Failed to clean up old log files", e, ErrorManager.GENERIC_FAILURE);
    }
  }
}
