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

#include "cmScanDepFormat.h"

#include <cstdio>
#include <utility>

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

#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>

#include "cmsys/FStream.hxx"
#include "cmsys/String.h"

#include "cmGeneratedFileStream.h"
#include "cmJSONState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

static bool ParseFilename(Json::Value const& val, std::string& result)
{
  if (val.isString()) {
    result = val.asString();
  } else {
    return false;
  }

  return true;
}

static Json::Value EncodeFilename(std::string const& path)
{
  std::string data;
  data.reserve(path.size());

  for (auto const& byte : path) {
    if (cmsysString_iscntrl(byte)) {
      // Control characters.
      data.append("\\u");
      char buf[5];
      std::snprintf(buf, sizeof(buf), "%04x", byte);
      data.append(buf);
    } else if (byte == '"' || byte == '\\') {
      // Special JSON characters.
      data.push_back('\\');
      data.push_back(byte);
    } else {
      // Other data.
      data.push_back(byte);
    }
  }

  return data;
}

#define PARSE_BLOB(val, res)                                                  \
  do {                                                                        \
    if (!ParseFilename(val, res)) {                                           \
      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", \
                                    arg_pp, ": invalid blob"));               \
      return false;                                                           \
    }                                                                         \
  } while (0)

#define PARSE_FILENAME(val, res)                                              \
  do {                                                                        \
    if (!ParseFilename(val, res)) {                                           \
      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", \
                                    arg_pp, ": invalid filename"));           \
      return false;                                                           \
    }                                                                         \
                                                                              \
    if (work_directory && !work_directory->empty() &&                         \
        !cmSystemTools::FileIsFullPath(res)) {                                \
      res = cmStrCat(*work_directory, '/', res);                              \
    }                                                                         \
  } while (0)

bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
                                 cmScanDepInfo* info)
{
  Json::Value ppio;
  Json::Value const& ppi = ppio;
  {
    cmJSONState parseState(arg_pp, &ppio);
    if (!parseState.errors.empty()) {
      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
                                    arg_pp, parseState.GetErrorMessage()));
      return false;
    }
  }

  Json::Value const& version = ppi["version"];
  if (version.asUInt() > 1) {
    cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
                                  arg_pp, ": version ", version.asString()));
    return false;
  }

  Json::Value const& rules = ppi["rules"];
  if (rules.isArray()) {
    if (rules.size() != 1) {
      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
                                    arg_pp, ": expected 1 source entry"));
      return false;
    }

    for (auto const& rule : rules) {
      cm::optional<std::string> work_directory;
      Json::Value const& workdir = rule["work-directory"];
      if (workdir.isString()) {
        std::string wd;
        PARSE_BLOB(workdir, wd);
        work_directory = std::move(wd);
      } else if (!workdir.isNull()) {
        cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
                                      arg_pp,
                                      ": work-directory is not a string"));
        return false;
      }

      if (rule.isMember("primary-output")) {
        Json::Value const& primary_output = rule["primary-output"];
        PARSE_FILENAME(primary_output, info->PrimaryOutput);
      }

      if (rule.isMember("outputs")) {
        Json::Value const& outputs = rule["outputs"];
        if (outputs.isArray()) {
          for (auto const& output : outputs) {
            std::string extra_output;
            PARSE_FILENAME(output, extra_output);

            info->ExtraOutputs.emplace_back(extra_output);
          }
        }
      }

      if (rule.isMember("provides")) {
        Json::Value const& provides = rule["provides"];
        if (!provides.isArray()) {
          cmSystemTools::Error(
            cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                     ": provides is not an array"));
          return false;
        }

        for (auto const& provide : provides) {
          cmSourceReqInfo provide_info;

          Json::Value const& logical_name = provide["logical-name"];
          PARSE_BLOB(logical_name, provide_info.LogicalName);

          if (provide.isMember("compiled-module-path")) {
            Json::Value const& compiled_module_path =
              provide["compiled-module-path"];
            PARSE_FILENAME(compiled_module_path,
                           provide_info.CompiledModulePath);
          }

          if (provide.isMember("unique-on-source-path")) {
            Json::Value const& unique_on_source_path =
              provide["unique-on-source-path"];
            if (!unique_on_source_path.isBool()) {
              cmSystemTools::Error(
                cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                         ": unique-on-source-path is not a boolean"));
              return false;
            }
            provide_info.UseSourcePath = unique_on_source_path.asBool();
          } else {
            provide_info.UseSourcePath = false;
          }

          if (provide.isMember("source-path")) {
            Json::Value const& source_path = provide["source-path"];
            PARSE_FILENAME(source_path, provide_info.SourcePath);
          } else if (provide_info.UseSourcePath) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                       ": source-path is missing"));
            return false;
          }

          if (provide.isMember("is-interface")) {
            Json::Value const& is_interface = provide["is-interface"];
            if (!is_interface.isBool()) {
              cmSystemTools::Error(
                cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                         ": is-interface is not a boolean"));
              return false;
            }
            provide_info.IsInterface = is_interface.asBool();
          } else {
            provide_info.IsInterface = true;
          }

          info->Provides.push_back(provide_info);
        }
      }

      if (rule.isMember("requires")) {
        Json::Value const& reqs = rule["requires"];
        if (!reqs.isArray()) {
          cmSystemTools::Error(
            cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                     ": requires is not an array"));
          return false;
        }

        for (auto const& require : reqs) {
          cmSourceReqInfo require_info;

          Json::Value const& logical_name = require["logical-name"];
          PARSE_BLOB(logical_name, require_info.LogicalName);

          if (require.isMember("compiled-module-path")) {
            Json::Value const& compiled_module_path =
              require["compiled-module-path"];
            PARSE_FILENAME(compiled_module_path,
                           require_info.CompiledModulePath);
          }

          if (require.isMember("unique-on-source-path")) {
            Json::Value const& unique_on_source_path =
              require["unique-on-source-path"];
            if (!unique_on_source_path.isBool()) {
              cmSystemTools::Error(
                cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                         ": unique-on-source-path is not a boolean"));
              return false;
            }
            require_info.UseSourcePath = unique_on_source_path.asBool();
          } else {
            require_info.UseSourcePath = false;
          }

          if (require.isMember("source-path")) {
            Json::Value const& source_path = require["source-path"];
            PARSE_FILENAME(source_path, require_info.SourcePath);
          } else if (require_info.UseSourcePath) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                       ": source-path is missing"));
            return false;
          }

          if (require.isMember("lookup-method")) {
            Json::Value const& lookup_method = require["lookup-method"];
            if (!lookup_method.isString()) {
              cmSystemTools::Error(
                cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
                         ": lookup-method is not a string"));
              return false;
            }

            std::string lookup_method_str = lookup_method.asString();
            if (lookup_method_str == "by-name"_s) {
              require_info.Method = LookupMethod::ByName;
            } else if (lookup_method_str == "include-angle"_s) {
              require_info.Method = LookupMethod::IncludeAngle;
            } else if (lookup_method_str == "include-quote"_s) {
              require_info.Method = LookupMethod::IncludeQuote;
            } else {
              cmSystemTools::Error(cmStrCat(
                "-E cmake_ninja_dyndep failed to parse ", arg_pp,
                ": lookup-method is not a valid: ", lookup_method_str));
              return false;
            }
          } else if (require_info.UseSourcePath) {
            require_info.Method = LookupMethod::ByName;
          }

          info->Requires.push_back(require_info);
        }
      }
    }
  }

  return true;
}

bool cmScanDepFormat_P1689_Write(std::string const& path,
                                 cmScanDepInfo const& info)
{
  Json::Value ddi(Json::objectValue);
  ddi["version"] = 0;
  ddi["revision"] = 0;

  Json::Value& rules = ddi["rules"] = Json::arrayValue;

  Json::Value rule(Json::objectValue);

  rule["primary-output"] = EncodeFilename(info.PrimaryOutput);

  Json::Value& rule_outputs = rule["outputs"] = Json::arrayValue;
  for (auto const& output : info.ExtraOutputs) {
    rule_outputs.append(EncodeFilename(output));
  }

  Json::Value& provides = rule["provides"] = Json::arrayValue;
  for (auto const& provide : info.Provides) {
    Json::Value provide_obj(Json::objectValue);
    auto const encoded = EncodeFilename(provide.LogicalName);
    provide_obj["logical-name"] = encoded;
    if (!provide.CompiledModulePath.empty()) {
      provide_obj["compiled-module-path"] =
        EncodeFilename(provide.CompiledModulePath);
    }

    if (provide.UseSourcePath) {
      provide_obj["unique-on-source-path"] = true;
      provide_obj["source-path"] = EncodeFilename(provide.SourcePath);
    } else if (!provide.SourcePath.empty()) {
      provide_obj["source-path"] = EncodeFilename(provide.SourcePath);
    }

    provide_obj["is-interface"] = provide.IsInterface;

    provides.append(provide_obj);
  }

  Json::Value& reqs = rule["requires"] = Json::arrayValue;
  for (auto const& require : info.Requires) {
    Json::Value require_obj(Json::objectValue);
    auto const encoded = EncodeFilename(require.LogicalName);
    require_obj["logical-name"] = encoded;
    if (!require.CompiledModulePath.empty()) {
      require_obj["compiled-module-path"] =
        EncodeFilename(require.CompiledModulePath);
    }

    if (require.UseSourcePath) {
      require_obj["unique-on-source-path"] = true;
      require_obj["source-path"] = EncodeFilename(require.SourcePath);
    } else if (!require.SourcePath.empty()) {
      require_obj["source-path"] = EncodeFilename(require.SourcePath);
    }

    char const* lookup_method = nullptr;
    switch (require.Method) {
      case LookupMethod::ByName:
        // No explicit value needed for the default.
        break;
      case LookupMethod::IncludeAngle:
        lookup_method = "include-angle";
        break;
      case LookupMethod::IncludeQuote:
        lookup_method = "include-quote";
        break;
    }
    if (lookup_method) {
      require_obj["lookup-method"] = lookup_method;
    }

    reqs.append(require_obj);
  }

  rules.append(rule);

  cmGeneratedFileStream ddif(path);
  ddif << ddi;

  return !!ddif;
}
