#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", "trace"
};
std::vector<std::string> const cmInstrumentationQuery::HookString{
  "postGenerate",    "preBuild",  "postBuild",        "preCMakeBuild",
  "postCMakeBuild",  "postCTest", "postCMakeInstall", "postCMakeWorkflow",
  "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;
}
