/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <vector>

#include <cm/optional>
#include <cm/string_view>

#include <cm3p/json/value.h>

#include "cmJSONState.h"
#include "cmStringAlgorithms.h"

template <typename T>
using cmJSONHelper =
  std::function<bool(T& out, const Json::Value* value, cmJSONState* state)>;

using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;

namespace JsonErrors {
enum ObjectError
{
  RequiredMissing,
  InvalidObject,
  ExtraField,
  MissingRequired
};
using ErrorGenerator = std::function<void(const Json::Value*, cmJSONState*)>;
using ObjectErrorGenerator =
  std::function<ErrorGenerator(ObjectError, const Json::Value::Members&)>;
ErrorGenerator EXPECTED_TYPE(const std::string& type);

void INVALID_STRING(const Json::Value* value, cmJSONState* state);

void INVALID_BOOL(const Json::Value* value, cmJSONState* state);

void INVALID_INT(const Json::Value* value, cmJSONState* state);

void INVALID_UINT(const Json::Value* value, cmJSONState* state);

ObjectErrorGenerator INVALID_NAMED_OBJECT(
  const std::function<std::string(const Json::Value*, cmJSONState*)>&
    nameGenerator);

ErrorGenerator INVALID_OBJECT(ObjectError errorType,
                              const Json::Value::Members& extraFields);

ErrorGenerator INVALID_NAMED_OBJECT_KEY(
  ObjectError errorType, const Json::Value::Members& extraFields);
}

struct cmJSONHelperBuilder
{

  template <typename T>
  class Object
  {
  public:
    Object(JsonErrors::ObjectErrorGenerator error = JsonErrors::INVALID_OBJECT,
           bool allowExtra = true)
      : Error(std::move(error))
      , AllowExtra(allowExtra)
    {
    }

    template <typename U, typename M, typename F>
    Object& Bind(const cm::string_view& name, M U::*member, F func,
                 bool required = true)
    {
      return this->BindPrivate(
        name,
        [func, member](T& out, const Json::Value* value, cmJSONState* state)
          -> bool { return func(out.*member, value, state); },
        required);
    }
    template <typename M, typename F>
    Object& Bind(const cm::string_view& name, std::nullptr_t, F func,
                 bool required = true)
    {
      return this->BindPrivate(
        name,
        [func](T& /*out*/, const Json::Value* value,
               cmJSONState* state) -> bool {
          M dummy;
          return func(dummy, value, state);
        },
        required);
    }
    template <typename F>
    Object& Bind(const cm::string_view& name, F func, bool required = true)
    {
      return this->BindPrivate(name, MemberFunction(func), required);
    }

    bool operator()(T& out, const Json::Value* value, cmJSONState* state) const
    {
      Json::Value::Members extraFields;
      bool success = true;
      if (!value && this->AnyRequired) {
        Error(JsonErrors::ObjectError::RequiredMissing, extraFields)(value,
                                                                     state);
        return false;
      }
      if (value && !value->isObject()) {
        Error(JsonErrors::ObjectError::InvalidObject, extraFields)(value,
                                                                   state);
        return false;
      }
      if (value) {
        extraFields = value->getMemberNames();
      }

      for (auto const& m : this->Members) {
        std::string name(m.Name.data(), m.Name.size());
        state->push_stack(name, value);
        if (value && value->isMember(name)) {
          if (!m.Function(out, &(*value)[name], state)) {
            success = false;
          }
          extraFields.erase(
            std::find(extraFields.begin(), extraFields.end(), name));
        } else if (!m.Required) {
          if (!m.Function(out, nullptr, state)) {
            success = false;
          }
        } else {
          Error(JsonErrors::ObjectError::MissingRequired, extraFields)(value,
                                                                       state);
          success = false;
        }
        state->pop_stack();
      }

      if (!this->AllowExtra && !extraFields.empty()) {
        Error(JsonErrors::ObjectError::ExtraField, extraFields)(value, state);
        success = false;
      }
      return success;
    }

  private:
    // Not a true cmJSONHelper, it just happens to match the signature
    using MemberFunction = std::function<bool(T& out, const Json::Value* value,
                                              cmJSONState* state)>;
    struct Member
    {
      cm::string_view Name;
      MemberFunction Function;
      bool Required;
    };
    std::vector<Member> Members;
    bool AnyRequired = false;
    JsonErrors::ObjectErrorGenerator Error;
    bool AllowExtra;

    Object& BindPrivate(const cm::string_view& name, MemberFunction&& func,
                        bool required)
    {
      Member m;
      m.Name = name;
      m.Function = std::move(func);
      m.Required = required;
      this->Members.push_back(std::move(m));
      if (required) {
        this->AnyRequired = true;
      }
      return *this;
    }
  };

  static cmJSONHelper<std::string> String(
    const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_STRING,
    const std::string& defval = "")
  {
    return [error, defval](std::string& out, const Json::Value* value,
                           cmJSONState* state) -> bool {
      if (!value) {
        out = defval;
        return true;
      }
      if (!value->isString()) {
        error(value, state);
        ;
        return false;
      }
      out = value->asString();
      return true;
    };
  };

  static cmJSONHelper<std::string> String(const std::string& defval)
  {
    return String(JsonErrors::INVALID_STRING, defval);
  };

  static cmJSONHelper<int> Int(
    const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_INT,
    int defval = 0)
  {
    return [error, defval](int& out, const Json::Value* value,
                           cmJSONState* state) -> bool {
      if (!value) {
        out = defval;
        return true;
      }
      if (!value->isInt()) {
        error(value, state);
        ;
        return false;
      }
      out = value->asInt();
      return true;
    };
  }

  static cmJSONHelper<int> Int(int defval)
  {
    return Int(JsonErrors::INVALID_INT, defval);
  };

  static cmJSONHelper<unsigned int> UInt(
    const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_UINT,
    unsigned int defval = 0)
  {
    return [error, defval](unsigned int& out, const Json::Value* value,
                           cmJSONState* state) -> bool {
      if (!value) {
        out = defval;
        return true;
      }
      if (!value->isUInt()) {
        error(value, state);
        ;
        return false;
      }
      out = value->asUInt();
      return true;
    };
  }

  static cmJSONHelper<unsigned int> UInt(unsigned int defval)
  {
    return UInt(JsonErrors::INVALID_UINT, defval);
  }

  static cmJSONHelper<bool> Bool(
    const JsonErrors::ErrorGenerator& error = JsonErrors::INVALID_BOOL,
    bool defval = false)
  {
    return [error, defval](bool& out, const Json::Value* value,
                           cmJSONState* state) -> bool {
      if (!value) {
        out = defval;
        return true;
      }
      if (!value->isBool()) {
        error(value, state);
        ;
        return false;
      }
      out = value->asBool();
      return true;
    };
  }

  static cmJSONHelper<bool> Bool(bool defval)
  {
    return Bool(JsonErrors::INVALID_BOOL, defval);
  }

  template <typename T, typename F, typename Filter>
  static cmJSONHelper<std::vector<T>> VectorFilter(
    const JsonErrors::ErrorGenerator& error, F func, Filter filter)
  {
    return [error, func, filter](std::vector<T>& out, const Json::Value* value,
                                 cmJSONState* state) -> bool {
      bool success = true;
      if (!value) {
        out.clear();
        return true;
      }
      if (!value->isArray()) {
        error(value, state);
        return false;
      }
      out.clear();
      int index = 0;
      for (auto const& item : *value) {
        state->push_stack(cmStrCat("$vector_item_", index++), &item);
        T t;
        if (!func(t, &item, state)) {
          success = false;
        }
        if (!filter(t)) {
          state->pop_stack();
          continue;
        }
        out.push_back(std::move(t));
        state->pop_stack();
      }
      return success;
    };
  }

  template <typename T, typename F>
  static cmJSONHelper<std::vector<T>> Vector(JsonErrors::ErrorGenerator error,
                                             F func)
  {
    return VectorFilter<T, F>(std::move(error), func,
                              [](const T&) { return true; });
  }

  template <typename T, typename F, typename Filter>
  static cmJSONHelper<std::map<std::string, T>> MapFilter(
    const JsonErrors::ErrorGenerator& error, F func, Filter filter)
  {
    return [error, func, filter](std::map<std::string, T>& out,
                                 const Json::Value* value,
                                 cmJSONState* state) -> bool {
      bool success = true;
      if (!value) {
        out.clear();
        return true;
      }
      if (!value->isObject()) {
        error(value, state);
        ;
        return false;
      }
      out.clear();
      for (auto const& key : value->getMemberNames()) {
        state->push_stack(cmStrCat(key, ""), &(*value)[key]);
        if (!filter(key)) {
          state->pop_stack();
          continue;
        }
        T t;
        if (!func(t, &(*value)[key], state)) {
          success = false;
        }
        out[key] = std::move(t);
        state->pop_stack();
      }
      return success;
    };
  }

  template <typename T, typename F>
  static cmJSONHelper<std::map<std::string, T>> Map(
    const JsonErrors::ErrorGenerator& error, F func)
  {
    return MapFilter<T, F>(error, func,
                           [](const std::string&) { return true; });
  }

  template <typename T, typename F>
  static cmJSONHelper<cm::optional<T>> Optional(F func)
  {
    return [func](cm::optional<T>& out, const Json::Value* value,
                  cmJSONState* state) -> bool {
      if (!value) {
        out.reset();
        return true;
      }
      out.emplace();
      return func(*out, value, state);
    };
  }

  template <typename T, typename F>
  static cmJSONHelper<T> Required(const JsonErrors::ErrorGenerator& error,
                                  F func)
  {
    return [error, func](T& out, const Json::Value* value,
                         cmJSONState* state) -> bool {
      if (!value) {
        error(value, state);
        ;
        return false;
      }
      return func(out, value, state);
    };
  }
};
