// Copyright 2020 The Pigweed Authors
//
// 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
//
//     https://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.

// This is a very basic direct output log implementation with no buffering.

#include "pw_log_basic/log_basic.h"

#include <cstring>

#include "pw_log/levels.h"
#include "pw_log_basic_private/config.h"
#include "pw_string/string_builder.h"
#include "pw_sys_io/sys_io.h"

// ANSI color constants to control the terminal. Not Windows compatible.
// clang-format off
#define MAGENTA   "\033[35m"
#define YELLOW    "\033[33m"
#define RED       "\033[31m"
#define GREEN     "\033[32m"
#define BLUE      "\033[96m"
#define BLACK     "\033[30m"
#define YELLOW_BG "\033[43m"
#define WHITE_BG  "\033[47m"
#define RED_BG    "\033[41m"
#define BOLD      "\033[1m"
#define RESET     "\033[0m"
// clang-format on

namespace pw::log_basic {
namespace {

const char* LogLevelToLogLevelName(int level) {
  switch (level) {
    // clang-format off
#if PW_EMOJI
    case PW_LOG_LEVEL_DEBUG    : return "👾" RESET;
    case PW_LOG_LEVEL_INFO     : return "ℹ️ " RESET;
    case PW_LOG_LEVEL_WARN     : return "⚠️ " RESET;
    case PW_LOG_LEVEL_ERROR    : return "❌" RESET;
    case PW_LOG_LEVEL_CRITICAL : return "☠️ " RESET;
    default: return "❔" RESET;
#else
    case PW_LOG_LEVEL_DEBUG    : return BLUE     BOLD        "DBG" RESET;
    case PW_LOG_LEVEL_INFO     : return MAGENTA  BOLD        "INF" RESET;
    case PW_LOG_LEVEL_WARN     : return YELLOW   BOLD        "WRN" RESET;
    case PW_LOG_LEVEL_ERROR    : return RED      BOLD        "ERR" RESET;
    case PW_LOG_LEVEL_CRITICAL : return BLACK    BOLD RED_BG "FTL" RESET;
    default                    : return GREEN    BOLD        "UNK" RESET;
#endif
      // clang-format on
  }
}

#if PW_LOG_SHOW_FILENAME
const char* GetFileBasename(const char* filename) {
  int length = std::strlen(filename);
  if (length == 0) {
    return filename;
  }

  // Start on the last character.
  // TODO(pwbug/38): This part of the function doesn't work for Windows paths.
  const char* basename = filename + std::strlen(filename) - 1;
  while (basename != filename && *basename != '/') {
    basename--;
  }
  if (*basename == '/') {
    basename++;
  }
  return basename;
}
#endif  // PW_LOG_SHOW_FILENAME

void (*write_log)(std::string_view) = [](std::string_view log) {
  sys_io::WriteLine(log)
      .IgnoreError();  // TODO(pwbug/387): Handle Status properly
};

}  // namespace

// This is a fully loaded, inefficient-at-the-callsite, log implementation.
extern "C" void pw_Log(int level,
                       unsigned int flags,
                       const char* module_name,
                       const char* file_name,
                       int line_number,
                       const char* function_name,
                       const char* message,
                       ...) {
  // Accumulate the log message in this buffer, then output it.
  pw::StringBuffer<150> buffer;

  // Column: Timestamp
  // Note that this macro method defaults to a no-op.
  PW_LOG_APPEND_TIMESTAMP(buffer);

  // Column: Filename
#if PW_LOG_SHOW_FILENAME
  buffer.Format(" %-30s:%4d |", GetFileBasename(file_name), line_number);
#else
  static_cast<void>(file_name);
  static_cast<void>(line_number);
#endif

  // Column: Function
#if PW_LOG_SHOW_FUNCTION
  buffer.Format(" %20s |", function_name);
#else
  static_cast<void>(function_name);
#endif

  // Column: Module
#if PW_LOG_SHOW_MODULE
  buffer << " " BOLD;
  buffer.Format("%3s", module_name);
  buffer << RESET " ";
#else
  static_cast<void>(module_name);
#endif  // PW_LOG_SHOW_MODULE

  // Column: Flag
#if PW_LOG_SHOW_FLAG
#if PW_EMOJI
  buffer << (flags ? "🚩" : "  ");
#else
  buffer << (flags ? "*" : "|");
#endif  // PW_EMOJI
  buffer << " ";
#else
  static_cast<void>(flags);
#endif  // PW_LOG_SHOW_FLAG

  // Column: Level
  buffer << LogLevelToLogLevelName(level) << "  ";

  // Column: Message
  va_list args;
  va_start(args, message);
  buffer.FormatVaList(message, args);
  va_end(args);

  // All done; flush the log.
  write_log(buffer);
}

void SetOutput(void (*log_output)(std::string_view log)) {
  write_log = log_output;
}

}  // namespace pw::log_basic
