// Copyright 2020 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 <lib/syslog/cpp/log_level.h>
#include <lib/syslog/cpp/logging_backend.h>
#include <lib/syslog/global.h>
#include <lib/zx/process.h>

#include <iostream>
#include <sstream>

static_assert(syslog::LOG_TRACE == FX_LOG_TRACE);
static_assert(syslog::LOG_DEBUG == FX_LOG_DEBUG);
static_assert(syslog::LOG_INFO == FX_LOG_INFO);
static_assert(syslog::LOG_WARNING == FX_LOG_WARNING);
static_assert(syslog::LOG_ERROR == FX_LOG_ERROR);
static_assert(syslog::LOG_FATAL == FX_LOG_FATAL);

namespace syslog_backend {

void SetLogSettings(const syslog::LogSettings& settings) {
  char process_name[ZX_MAX_NAME_LEN] = "";
  zx_status_t status =
      zx::process::self()->get_property(ZX_PROP_NAME, process_name, sizeof(process_name));
  if (status != ZX_OK)
    process_name[0] = '\0';
  syslog_backend::SetLogSettings(settings, {process_name});
}

void SetLogSettings(const syslog::LogSettings& settings,
                    const std::initializer_list<std::string>& tags) {
  const char* ctags[FX_LOG_MAX_TAGS];
  size_t num_tags = 0;
  for (auto& tag : tags) {
    ctags[num_tags++] = tag.c_str();
    if (num_tags >= FX_LOG_MAX_TAGS)
      break;
  }
  int fd = -1;
  if (!settings.log_file.empty()) {
    fd = open(settings.log_file.c_str(), O_WRONLY | O_CREAT | O_APPEND);
    if (fd < 0) {
      fd = -1;
    }
  }
  fx_logger_config_t config = {.min_severity = settings.min_log_level,
                               .console_fd = fd,
                               .log_service_channel = ZX_HANDLE_INVALID,
                               .tags = ctags,
                               .num_tags = num_tags};
  fx_log_reconfigure(&config);
}

syslog::LogSeverity GetMinLogLevel() {
  return static_cast<syslog::LogSeverity>(fx_logger_get_min_severity(fx_log_get_logger()));
}

void WriteLogValue(syslog::LogSeverity severity, const char* file, unsigned int line,
                   const char* condition, const syslog::LogValue& value, const char* msg) {
  std::string message(msg);
  auto rest = value.ToString();
  if (!rest.empty()) {
    message += " " + value.ToString();
  }
  WriteLog(severity, file, line, nullptr, condition, message);
}

void WriteLog(syslog::LogSeverity severity, const char* file, unsigned int line, const char* tag,
              const char* condition, const std::string& msg) {
  std::ostringstream stream;

  stream << "[" << file << "(" << line << ")] ";

  if (condition)
    stream << "Check failed: " << condition << ". ";

  stream << msg;

  // Write fatal logs to stderr as well because death tests sometimes verify a certain
  // log message was printed prior to the crash.
  // TODO(samans): Convert tests to not depend on stderr. https://fxbug.dev/49593
  if (severity == syslog::LOG_FATAL)
    std::cerr << stream.str() << std::endl;

  fx_logger_t* logger = fx_log_get_logger();
  fx_logger_log(logger, severity, tag, stream.str().c_str());
}

}  // namespace syslog_backend
