/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmMessageCommand.h"

#include <cassert>
#include <memory>
#include <utility>

#include <cm/string_view>
#include <cmext/string_view>

#include "cmConfigureLog.h"
#include "cmExecutionStatus.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"

#ifdef CMake_ENABLE_DEBUGGER
#  include "cmDebuggerAdapter.h"
#endif

namespace {

std::string IndentText(std::string text, cmMakefile& mf)
{
  auto indent =
    cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT") }.join("");

  auto const showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
    mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
  if (showContext) {
    auto context =
      cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT") }.join(".");
    if (!context.empty()) {
      indent.insert(0u, cmStrCat("["_s, context, "] "_s));
    }
  }

  if (!indent.empty()) {
    cmSystemTools::ReplaceString(text, "\n", "\n" + indent);
    text.insert(0u, indent);
  }
  return text;
}

void ReportCheckResult(cm::string_view what, std::string result,
                       cmMakefile& mf)
{
  if (mf.GetCMakeInstance()->HasCheckInProgress()) {
    auto text = mf.GetCMakeInstance()->GetTopCheckInProgressMessage() + " - " +
      std::move(result);
    mf.DisplayStatus(IndentText(std::move(text), mf), -1);
  } else {
    mf.GetMessenger()->DisplayMessage(
      MessageType::AUTHOR_WARNING,
      cmStrCat("Ignored "_s, what, " without CHECK_START"_s),
      mf.GetBacktrace());
  }
}

namespace {
#ifndef CMAKE_BOOTSTRAP
void WriteMessageEvent(cmConfigureLog& log, cmMakefile const& mf,
                       std::string const& message)
{
  // Keep in sync with cmFileAPIConfigureLog's DumpEventKindNames.
  static std::vector<unsigned int> const LogVersionsWithMessageV1{ 1 };

  if (log.IsAnyLogVersionEnabled(LogVersionsWithMessageV1)) {
    log.BeginEvent("message-v1", mf);
    log.WriteLiteralTextBlock("message"_s, message);
    log.EndEvent();
  }
}
#endif
}

} // anonymous namespace

// cmLibraryCommand
bool cmMessageCommand(std::vector<std::string> const& args,
                      cmExecutionStatus& status)
{
  if (args.empty()) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  auto& mf = status.GetMakefile();

  auto i = args.cbegin();

  auto type = MessageType::MESSAGE;
  auto fatal = false;
  auto level = Message::LogLevel::LOG_UNDEFINED;
  auto checkingType = Message::CheckType::UNDEFINED;
  if (*i == "SEND_ERROR") {
    type = MessageType::FATAL_ERROR;
    level = Message::LogLevel::LOG_ERROR;
    ++i;
  } else if (*i == "FATAL_ERROR") {
    fatal = true;
    type = MessageType::FATAL_ERROR;
    level = Message::LogLevel::LOG_ERROR;
    ++i;
  } else if (*i == "WARNING") {
    type = MessageType::WARNING;
    level = Message::LogLevel::LOG_WARNING;
    ++i;
  } else if (*i == "AUTHOR_WARNING") {
    if (mf.IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
        !mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
      fatal = true;
      type = MessageType::AUTHOR_ERROR;
      level = Message::LogLevel::LOG_ERROR;
    } else if (!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
      type = MessageType::AUTHOR_WARNING;
      level = Message::LogLevel::LOG_WARNING;
    } else {
      return true;
    }
    ++i;
  } else if (*i == "CHECK_START") {
    level = Message::LogLevel::LOG_STATUS;
    checkingType = Message::CheckType::CHECK_START;
    ++i;
  } else if (*i == "CHECK_PASS") {
    level = Message::LogLevel::LOG_STATUS;
    checkingType = Message::CheckType::CHECK_PASS;
    ++i;
  } else if (*i == "CHECK_FAIL") {
    level = Message::LogLevel::LOG_STATUS;
    checkingType = Message::CheckType::CHECK_FAIL;
    ++i;
  } else if (*i == "CONFIGURE_LOG") {
#ifndef CMAKE_BOOTSTRAP
    if (cmConfigureLog* log = mf.GetCMakeInstance()->GetConfigureLog()) {
      ++i;
      WriteMessageEvent(*log, mf, cmJoin(cmMakeRange(i, args.cend()), ""_s));
    }
#endif
    return true;
  } else if (*i == "STATUS") {
    level = Message::LogLevel::LOG_STATUS;
    ++i;
  } else if (*i == "VERBOSE") {
    level = Message::LogLevel::LOG_VERBOSE;
    ++i;
  } else if (*i == "DEBUG") {
    level = Message::LogLevel::LOG_DEBUG;
    ++i;
  } else if (*i == "TRACE") {
    level = Message::LogLevel::LOG_TRACE;
    ++i;
  } else if (*i == "DEPRECATION") {
    if (mf.IsOn("CMAKE_ERROR_DEPRECATED")) {
      fatal = true;
      type = MessageType::DEPRECATION_ERROR;
      level = Message::LogLevel::LOG_ERROR;
    } else if (!mf.IsSet("CMAKE_WARN_DEPRECATED") ||
               mf.IsOn("CMAKE_WARN_DEPRECATED")) {
      type = MessageType::DEPRECATION_WARNING;
      level = Message::LogLevel::LOG_WARNING;
    } else {
      return true;
    }
    ++i;
  } else if (*i == "NOTICE") {
    // `NOTICE` message type is going to be output to stderr
    level = Message::LogLevel::LOG_NOTICE;
    ++i;
  } else {
    // Messages w/o any type are `NOTICE`s
    level = Message::LogLevel::LOG_NOTICE;
  }
  assert("Message log level expected to be set" &&
         level != Message::LogLevel::LOG_UNDEFINED);

  Message::LogLevel desiredLevel = mf.GetCurrentLogLevel();

  if (desiredLevel < level) {
    // Suppress the message
    return true;
  }

  auto message = cmJoin(cmMakeRange(i, args.cend()), "");

  switch (level) {
    case Message::LogLevel::LOG_ERROR:
    case Message::LogLevel::LOG_WARNING:
      // we've overridden the message type, above, so display it directly
      mf.GetMessenger()->DisplayMessage(type, message, mf.GetBacktrace());
      break;

    case Message::LogLevel::LOG_NOTICE:
      cmSystemTools::Message(IndentText(message, mf));
#ifdef CMake_ENABLE_DEBUGGER
      if (mf.GetCMakeInstance()->GetDebugAdapter()) {
        mf.GetCMakeInstance()->GetDebugAdapter()->OnMessageOutput(type,
                                                                  message);
      }
#endif
      break;

    case Message::LogLevel::LOG_STATUS:
      switch (checkingType) {
        case Message::CheckType::CHECK_START:
          mf.DisplayStatus(IndentText(message, mf), -1);
          mf.GetCMakeInstance()->PushCheckInProgressMessage(message);
          break;

        case Message::CheckType::CHECK_PASS:
          ReportCheckResult("CHECK_PASS"_s, message, mf);
          break;

        case Message::CheckType::CHECK_FAIL:
          ReportCheckResult("CHECK_FAIL"_s, message, mf);
          break;

        default:
          mf.DisplayStatus(IndentText(message, mf), -1);
          break;
      }
      break;

    case Message::LogLevel::LOG_VERBOSE:
    case Message::LogLevel::LOG_DEBUG:
    case Message::LogLevel::LOG_TRACE:
      mf.DisplayStatus(IndentText(message, mf), -1);
      break;

    default:
      assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
             false);
      break;
  }

  if (fatal) {
    cmSystemTools::SetFatalErrorOccurred();
  }
  return true;
}
