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

#include "cmJSONHelpers.h"

#include <functional>
#include <string>
#include <vector>

#include <cm3p/json/value.h>

#include "cmJSONState.h"

namespace JsonErrors {
ErrorGenerator EXPECTED_TYPE(std::string const& type)
{
  return [type](Json::Value const* value, cmJSONState* state) -> void {
    if (state->key().empty()) {
      state->AddErrorAtValue(cmStrCat("Expected ", type), value);
      return;
    }
    std::string errMsg = cmStrCat('"', state->key(), "\" expected ", type);
    if (value && value->isConvertibleTo(Json::ValueType::stringValue)) {
      errMsg = cmStrCat(errMsg, ", got: ", value->asString());
    }
    state->AddErrorAtValue(errMsg, value);
  };
}

void INVALID_STRING(Json::Value const* value, cmJSONState* state)
{
  JsonErrors::EXPECTED_TYPE("a string")(value, state);
}

void INVALID_BOOL(Json::Value const* value, cmJSONState* state)
{
  JsonErrors::EXPECTED_TYPE("a bool")(value, state);
}

void INVALID_INT(Json::Value const* value, cmJSONState* state)
{
  JsonErrors::EXPECTED_TYPE("an integer")(value, state);
}

void INVALID_UINT(Json::Value const* value, cmJSONState* state)
{
  JsonErrors::EXPECTED_TYPE("an unsigned integer")(value, state);
}

ObjectErrorGenerator INVALID_NAMED_OBJECT(
  std::function<std::string(Json::Value const*, cmJSONState*)> const&
    nameGenerator)
{
#if defined(__GNUC__) && __GNUC__ >= 15
#  define CM_GCC_diagnostic_push_Wmaybe_uninitialized
#  pragma GCC diagnostic push
#  pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
  return [nameGenerator](
           ObjectError errorType,
           Json::Value::Members const& extraFields) -> ErrorGenerator {
    return [nameGenerator, errorType, extraFields](
             Json::Value const* value, cmJSONState* state) -> void {
      std::string name = nameGenerator(value, state);
      switch (errorType) {
        case ObjectError::RequiredMissing:
          state->AddErrorAtValue(cmStrCat("Invalid Required ", name), value);
          break;
        case ObjectError::InvalidObject:
          state->AddErrorAtValue(cmStrCat("Invalid ", name), value);
          break;
        case ObjectError::ExtraField: {
          for (auto const& member : extraFields) {
            if (value) {
              state->AddErrorAtValue(
                cmStrCat("Invalid extra field \"", member, "\" in ", name),
                &(*value)[member]);
            } else {
              state->AddError(
                cmStrCat("Invalid extra field \"", member, "\" in ", name));
            }
          }
        } break;
        case ObjectError::MissingRequired:
          state->AddErrorAtValue(cmStrCat("Missing required field \"",
                                          state->key(), "\" in ", name),
                                 value);
          break;
      }
    };
  };
#ifdef CM_GCC_diagnostic_push_Wmaybe_uninitialized
#  pragma GCC diagnostic pop
#  undef CM_GCC_diagnostic_push_Wmaybe_uninitialized
#endif
}

ErrorGenerator INVALID_OBJECT(ObjectError errorType,
                              Json::Value::Members const& extraFields)
{
  return INVALID_NAMED_OBJECT(
    [](Json::Value const*, cmJSONState*) -> std::string { return "Object"; })(
    errorType, extraFields);
}

ErrorGenerator INVALID_NAMED_OBJECT_KEY(
  ObjectError errorType, Json::Value::Members const& extraFields)
{
  return INVALID_NAMED_OBJECT(
    [](Json::Value const*, cmJSONState* state) -> std::string {
      for (auto it = state->parseStack.rbegin();
           it != state->parseStack.rend(); ++it) {
        if (it->first.rfind("$vector_item_", 0) == 0) {
          continue;
        }
        return cmStrCat('"', it->first, '"');
      }
      return "root";
    })(errorType, extraFields);
}
}
