// Copyright 2017 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.worker;

import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;

/** A well-formatted error message that is easy to read and easy to create. */
@AutoValue
abstract class ErrorMessage {
  abstract String message();

  @Override
  public String toString() {
    return message();
  }

  public static Builder builder() {
    return new Builder();
  }

  public static final class Builder {
    private String message = "Unknown error";
    private Path logFile;
    private String logText = "";
    private int logSizeLimit = Integer.MAX_VALUE;
    private Exception exception;

    private Builder() {}

    /** Sets the main text of this error message. */
    public Builder message(String message) {
      Preconditions.checkNotNull(message);
      this.message = message.isEmpty() ? "Unknown error" : message.trim();
      return this;
    }

    /** Sets the log file that should be printed as part of the error message. */
    public Builder logFile(Path logFile) {
      Preconditions.checkNotNull(logFile);
      try {
        this.logFile = logFile;
        return logText(FileSystemUtils.readContent(logFile, UTF_8));
      } catch (IOException e) {
        logSizeLimit(Integer.MAX_VALUE);
        return logText(
            "ERROR: IOException while trying to read log file:\n"
                + Throwables.getStackTraceAsString(e));
      }
    }

    /**
     * Sets additional text, which is to be presented as a log file in the error message.
     *
     * <p>If the log originally comes from a file, it is recommended to use {@link #logFile}
     * instead, because then the path to the log file can be printed together with the message.
     */
    public Builder logText(String logText) {
      Preconditions.checkNotNull(logText);
      // Set the log text to "(empty)" when the passed in string is empty, otherwise error messages
      // like "Something failed. Check below log for details:" would be pretty confusing for users.
      this.logText = logText.isEmpty() ? "(empty)" : logText.trim();
      return this;
    }

    /**
     * If the log file or text of this error message is longer than the character limit set via this
     * method, it will be truncated so that only the last X characters of the log are printed.
     */
    public Builder logSizeLimit(int logSizeLimit) {
      Preconditions.checkArgument(logSizeLimit > 0, "logSizeLimit must be positive");
      this.logSizeLimit = logSizeLimit;
      return this;
    }

    /** Lets the error message contain the details of an exception. */
    public Builder exception(Exception e) {
      this.exception = e;
      return this;
    }

    /** Builds and returns the formatted error message. */
    public ErrorMessage build() {
      StringBuilder sb = new StringBuilder(message);

      if (exception != null) {
        sb.append("\n\n---8<---8<--- Exception details ---8<---8<---\n");
        sb.append(Throwables.getStackTraceAsString(exception).trim());
        sb.append("\n---8<---8<--- End of exception details ---8<---8<---");
      }

      if (!logText.isEmpty()) {
        sb.append("\n\n---8<---8<--- Start of log");
        if (logText.length() > logSizeLimit) {
          sb.append(" snippet");
        }
        if (logFile != null) {
          sb.append(", file at ");
          sb.append(logFile.getPathString());
        }
        sb.append(" ---8<---8<---\n");

        // If the length of the log is longer than the limit, print only the last part.
        if (logText.length() > logSizeLimit) {
          sb.append("[... truncated ...]\n");
          sb.append(logText, logText.length() - logSizeLimit, logText.length());
          sb.append("\n---8<---8<--- End of log snippet, ");
          sb.append(logText.length() - logSizeLimit);
          sb.append(" chars omitted ---8<---8<---");
        } else {
          sb.append(logText);
          sb.append("\n---8<---8<--- End of log ---8<---8<---");
        }
      }

      return new AutoValue_ErrorMessage(sb.toString());
    }
  }
}
