#include "cmInstrumentationQuery.h"

#include <algorithm>
#include <ctime>
#include <functional>
#include <iostream>
#include <iterator>
#include <set>
#include <vector>

#include <cmext/string_view>

#include <cm3p/json/value.h>

#include "cmJSONHelpers.h"
#include "cmStringAlgorithms.h"

std::vector<std::string> const cmInstrumentationQuery::OptionString{
  "staticSystemInformation", "dynamicSystemInformation", "cdashSubmit",
  "cdashVerbose"
};
std::vector<std::string> const cmInstrumentationQuery::HookString{
  "postGenerate",  "preBuild",        "postBuild",
  "preCMakeBuild", "postCMakeBuild",  "postTest",
  "postInstall",   "prepareForCDash", "manual"
};

namespace ErrorMessages {
using ErrorGenerator =
  std::function<void(Json::Value const*, cmJSONState* state)>;
ErrorGenerator ErrorGeneratorBuilder(std::string const& errorMessage)
{
  return [errorMessage](Json::Value const* value, cmJSONState* state) -> void {
    state->AddErrorAtValue(errorMessage, value);
  };
};

static ErrorGenerator InvalidArray = ErrorGeneratorBuilder("Invalid Array");
JsonErrors::ErrorGenerator InvalidRootQueryObject(
  JsonErrors::ObjectError errorType, Json::Value::Members const& extraFields)
{
  return JsonErrors::INVALID_NAMED_OBJECT(
    [](Json::Value const*, cmJSONState*) -> std::string {
      return "root object";
    })(errorType, extraFields);
}
};

using JSONHelperBuilder = cmJSONHelperBuilder;

template <typename E>
static std::function<bool(E&, Json::Value const*, cmJSONState*)> EnumHelper(
  std::vector<std::string> const toString, std::string const& type)
{
  return [toString, type](E& out, Json::Value const* value,
                          cmJSONState* state) -> bool {
    for (size_t i = 0; i < toString.size(); ++i) {
      if (value->asString() == toString[i]) {
        out = (E)i;
        return true;
      }
    }
    state->AddErrorAtValue(
      cmStrCat("Not a valid ", type, ": \"", value->asString(), '"'), value);
    return false;
  };
}
static auto const OptionHelper = EnumHelper<cmInstrumentationQuery::Option>(
  cmInstrumentationQuery::OptionString, "option");
static auto const QueryListHelper =
  JSONHelperBuilder::Vector<cmInstrumentationQuery::Option>(
    ErrorMessages::InvalidArray, OptionHelper);
static auto const HookHelper = EnumHelper<cmInstrumentationQuery::Hook>(
  cmInstrumentationQuery::HookString, "hook");
static auto const HookListHelper =
  JSONHelperBuilder::Vector<cmInstrumentationQuery::Hook>(
    ErrorMessages::InvalidArray, HookHelper);
static auto const CallbackHelper = JSONHelperBuilder::String();
static auto const CallbackListHelper = JSONHelperBuilder::Vector<std::string>(
  ErrorMessages::InvalidArray, CallbackHelper);
static auto const VersionHelper = JSONHelperBuilder::Int();

using QueryRoot = cmInstrumentationQuery::QueryJSONRoot;

static auto const QueryRootHelper =
  JSONHelperBuilder::Object<QueryRoot>(ErrorMessages::InvalidRootQueryObject,
                                       false)
    .Bind("version"_s, &QueryRoot::version, VersionHelper, true)
    .Bind("options"_s, &QueryRoot::options, QueryListHelper, false)
    .Bind("hooks"_s, &QueryRoot::hooks, HookListHelper, false)
    .Bind("callbacks"_s, &QueryRoot::callbacks, CallbackListHelper, false);

bool cmInstrumentationQuery::ReadJSON(std::string const& filename,
                                      std::string& errorMessage,
                                      std::set<Option>& options,
                                      std::set<Hook>& hooks,
                                      std::vector<std::string>& callbacks)
{
  Json::Value root;
  this->parseState = cmJSONState(filename, &root);
  if (!this->parseState.errors.empty()) {
    std::cerr << this->parseState.GetErrorMessage(true) << std::endl;
    return false;
  }
  if (!QueryRootHelper(this->queryRoot, &root, &this->parseState)) {
    errorMessage = this->parseState.GetErrorMessage(true);
    return false;
  }
  std::move(this->queryRoot.options.begin(), this->queryRoot.options.end(),
            std::inserter(options, options.end()));
  std::move(this->queryRoot.hooks.begin(), this->queryRoot.hooks.end(),
            std::inserter(hooks, hooks.end()));
  std::move(this->queryRoot.callbacks.begin(), this->queryRoot.callbacks.end(),
            std::back_inserter(callbacks));
  return true;
}
