// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/statusor/status_macros.h"

#include <algorithm>

#include <google/protobuf/stubs/strutil.h>

#include "glog/logging.h"
#include "src/lib/util/status.h"

namespace cobalt::lib::statusor::status_macros {

using cobalt::util::Status;

static Status MakeStatus(cobalt::util::StatusCode code, const std::string& message) {
  return Status(code, message);
}

// Log the error at the given severity, optionally with a stack trace.
// If log_severity is NUM_SEVERITIES, nothing is logged.
static void LogError(const Status& status, const char* /*filename*/, int /*line*/, int log_severity,
                     bool /*should_log_stack_trace*/) {
  if (log_severity != google::NUM_SEVERITIES) {
    std::string stack_trace;
    switch (log_severity) {
      case google::INFO:
        LOG(INFO) << status.error_message();
        break;
      case google::WARNING:
        LOG(WARNING) << status.error_message();
        break;
      case google::ERROR:
        LOG(ERROR) << status.error_message();
        break;
      case google::FATAL:
        LOG(FATAL) << status.error_message();
        break;
      case google::NUM_SEVERITIES:
        break;
      default:
        LOG(FATAL) << "Unknown LOG severity " << log_severity;
    }
  }
}

// Make a Status with a code, error message and payload,
// and also send it to LOG(<log_severity>) using the given filename
// and line (unless should_log is false, or log_severity is
// NUM_SEVERITIES).  If should_log_stack_trace is true, the stack
// trace is included in the log message (ignored if should_log is
// false).
static Status MakeError(const char* filename, int line, cobalt::util::StatusCode code,
                        const std::string& message, bool should_log, int log_severity,
                        bool should_log_stack_trace) {
  if (code == cobalt::util::StatusCode::OK) {
    LOG(ERROR) << "Cannot create error with status OK";
    code = cobalt::util::StatusCode::UNKNOWN;
  }
  const Status status = MakeStatus(code, message);
  if (should_log) {
    LogError(status, filename, line, log_severity, should_log_stack_trace);
  }
  return status;
}

// This method is written out-of-line rather than in the header to avoid
// generating a lot of inline code for error cases in all callers.
void MakeErrorStream::CheckNotDone() const { impl_->CheckNotDone(); }

MakeErrorStream::Impl::Impl(const char* file, int line, cobalt::util::StatusCode code,
                            MakeErrorStream* error_stream, bool is_logged_by_default)
    : file_(file),
      line_(line),
      code_(code),
      is_done_(false),
      should_log_(is_logged_by_default),
      log_severity_(google::ERROR),
      should_log_stack_trace_(false),
      make_error_stream_with_output_wrapper_(error_stream) {}

MakeErrorStream::Impl::Impl(const Status& status, PriorMessageHandling prior_message_handling,
                            const char* file, int line, MakeErrorStream* error_stream)
    : file_(file),
      line_(line),
      // Make sure we show some error, even if the call is incorrect.
      code_(!status.ok() ? status.error_code() : cobalt::util::StatusCode::UNKNOWN),
      prior_message_handling_(prior_message_handling),
      prior_message_(status.error_message()),
      is_done_(false),
      // Error code type is not visible here, so we can't call
      // IsLoggedByDefault.
      should_log_(true),
      log_severity_(google::ERROR),
      should_log_stack_trace_(false),
      make_error_stream_with_output_wrapper_(error_stream) {
  DCHECK(!status.ok()) << "Attempted to append/prepend error text to status OK";
}

MakeErrorStream::Impl::~Impl() {
  // Note: error messages refer to the public MakeErrorStream class.

  if (!is_done_) {
    LOG(ERROR) << "MakeErrorStream destructed without getting Status: " << file_ << ":" << line_
               << " " << stream_.str();
  }
}

Status MakeErrorStream::Impl::GetStatus() {
  // Note: error messages refer to the public MakeErrorStream class.

  // Getting a Status object out more than once is not harmful, but
  // it doesn't match the expected pattern, where the stream is constructed
  // as a temporary, loaded with a message, and then casted to Status.
  if (is_done_) {
    LOG(ERROR) << "MakeErrorStream got Status more than once: " << file_ << ":" << line_ << " "
               << stream_.str();
  }

  is_done_ = true;

  const std::string& stream_str = stream_.str();
  const std::string str = prior_message_handling_ == kAppendToPriorMessage
                              ? google::protobuf::StrCat(prior_message_, stream_str)
                              : google::protobuf::StrCat(stream_str, prior_message_);
  if (str.empty()) {
    return MakeError(file_, line_, code_,
                     google::protobuf::StrCat(str, "Error without message at ", file_, ":", line_),
                     true /* should_log */, google::ERROR /* log_severity */,
                     should_log_stack_trace_);
  }
  return MakeError(file_, line_, code_, str, should_log_, log_severity_, should_log_stack_trace_);
}

void MakeErrorStream::Impl::CheckNotDone() const {
  if (is_done_) {
    LOG(ERROR) << "MakeErrorStream shift called after getting Status: " << file_ << ":" << line_
               << " " << stream_.str();
  }
}

}  // namespace cobalt::lib::statusor::status_macros
