// Copyright (c) 2012 The Chromium OS 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 "brillo/syslog_logging.h"

#include <syslog.h>
#include <unistd.h>

#include <string>

// syslog.h and base/logging.h both try to #define LOG_INFO and LOG_WARNING.
// We need to #undef at least these two before including base/logging.h.  The
// others are included to be consistent.
namespace {
const int kSyslogDebug = LOG_DEBUG;
const int kSyslogInfo = LOG_INFO;
const int kSyslogWarning = LOG_WARNING;
const int kSyslogError = LOG_ERR;
const int kSyslogCritical = LOG_CRIT;

#undef LOG_INFO
#undef LOG_WARNING
#undef LOG_ERR
#undef LOG_CRIT
}  // namespace

#include <base/logging.h>

static std::string s_ident;        // NOLINT(runtime/string)
static std::string s_accumulated;  // NOLINT(runtime/string)
static bool s_accumulate;
static bool s_log_to_syslog;
static bool s_log_to_stderr;
static bool s_log_header;

static bool HandleMessage(int severity,
                          const char* /* file */,
                          int /* line */,
                          size_t message_start,
                          const std::string& message) {
  switch (severity) {
    case logging::LOGGING_INFO:
      severity = kSyslogInfo;
      break;

    case logging::LOGGING_WARNING:
      severity = kSyslogWarning;
      break;

    case logging::LOGGING_ERROR:
      severity = kSyslogError;
      break;

    case logging::LOGGING_FATAL:
      severity = kSyslogCritical;
      break;

    default:
      severity = kSyslogDebug;
      break;
  }

  const char* str;
  if (s_log_header) {
    str = message.c_str();
  } else {
    str = message.c_str() + message_start;
  }

  if (s_log_to_syslog)
    syslog(severity, "%s", str);
  if (s_accumulate)
    s_accumulated.append(str);
  return !s_log_to_stderr && severity != kSyslogCritical;
}

namespace brillo {
void SetLogFlags(int log_flags) {
  s_log_to_syslog = (log_flags & kLogToSyslog) != 0;
  s_log_to_stderr = (log_flags & kLogToStderr) != 0;
  if ((log_flags & kLogToStderrIfTty) && isatty(0))
    s_log_to_stderr = true;
  s_log_header = (log_flags & kLogHeader) != 0;
}
int GetLogFlags() {
  int flags = 0;
  flags |= (s_log_to_syslog) ? kLogToSyslog : 0;
  flags |= (s_log_to_stderr) ? kLogToStderr : 0;
  flags |= (s_log_header) ? kLogHeader : 0;
  return flags;
}
void InitLog(int init_flags) {
  logging::LoggingSettings settings;
  settings.logging_dest =
      logging::LOG_TO_SYSTEM_DEBUG_LOG | logging::LOG_TO_STDERR;
  logging::InitLogging(settings);

  const bool kOptionPID = false;
  const bool kOptionTID = false;
  const bool kOptionTimestamp = false;
  const bool kOptionTickcount = false;
  logging::SetLogItems(kOptionPID, kOptionTID, kOptionTimestamp,
                       kOptionTickcount);
  logging::SetLogMessageHandler(HandleMessage);
  SetLogFlags(init_flags);
}
void OpenLog(const char* ident, bool log_pid) {
  s_ident = ident;
  openlog(s_ident.c_str(), log_pid ? LOG_PID : 0, LOG_USER);
}
void LogToString(bool enabled) {
  s_accumulate = enabled;
}
std::string GetLog() {
  return s_accumulated;
}
void ClearLog() {
  s_accumulated.clear();
}
bool FindLog(const char* string) {
  return s_accumulated.find(string) != std::string::npos;
}
}  // namespace brillo
