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

#include "cmCxxModuleMetadata.h"

#include <algorithm>
#include <set>
#include <string>
#include <utility>

#include <cmext/string_view>

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

#include "cmsys/FStream.hxx"

#include "cmFileSet.h"
#include "cmFileSetMetadata.h"
#include "cmGeneratedFileStream.h"
#include "cmJSONState.h"
#include "cmListFileCache.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"

namespace {

bool JsonIsStringArray(Json::Value const& v)
{
  return v.isArray() &&
    std::all_of(v.begin(), v.end(),
                [](Json::Value const& it) { return it.isString(); });
}

bool ParsePreprocessorDefine(Json::Value& dval,
                             cmCxxModuleMetadata::PreprocessorDefineData& out,
                             cmJSONState* state)
{
  if (!dval.isObject()) {
    state->AddErrorAtValue("each entry in 'definitions' must be an object",
                           &dval);
    return false;
  }

  if (!dval.isMember("name") || !dval["name"].isString() ||
      dval["name"].asString().empty()) {
    state->AddErrorAtValue(
      "preprocessor definition requires a non-empty 'name'", &dval["name"]);
    return false;
  }
  out.Name = dval["name"].asString();

  if (dval.isMember("value")) {
    if (dval["value"].isString()) {
      out.Value = dval["value"].asString();
    } else if (!dval["value"].isNull()) {
      state->AddErrorAtValue(
        "'value' in preprocessor definition must be string or null",
        &dval["value"]);
      return false;
    }
  }

  if (dval.isMember("undef")) {
    if (!dval["undef"].isBool()) {
      state->AddErrorAtValue(
        "'undef' in preprocessor definition must be boolean", &dval["undef"]);
      return false;
    }
    out.Undef = dval["undef"].asBool();
  }

  return true;
}

bool ParseCMakeLocalArgumentsVendor(
  Json::Value& cmlav, cmCxxModuleMetadata::LocalArgumentsData& out,
  cmJSONState* state)
{

  if (!cmlav.isObject()) {
    state->AddErrorAtValue("'vendor' must be an object", &cmlav);
    return false;
  }

  if (cmlav.isMember("compile-options")) {
    if (!JsonIsStringArray(cmlav["compile-options"])) {
      state->AddErrorAtValue("'compile-options' must be an array of strings",
                             &cmlav["compile-options"]);
      return false;
    }
    for (auto const& s : cmlav["compile-options"]) {
      out.CompileOptions.push_back(s.asString());
    }
  }

  if (cmlav.isMember("compile-features")) {
    if (!JsonIsStringArray(cmlav["compile-features"])) {
      state->AddErrorAtValue("'compile-features' must be an array of strings",
                             &cmlav["compile-features"]);
      return false;
    }
    for (auto const& s : cmlav["compile-features"]) {
      out.CompileFeatures.push_back(s.asString());
    }
  }

  return true;
}

bool ParseLocalArguments(Json::Value& lav,
                         cmCxxModuleMetadata::LocalArgumentsData& out,
                         cmJSONState* state)
{
  if (!lav.isObject()) {
    state->AddErrorAtValue("'local-arguments' must be an object", &lav);
    return false;
  }

  if (lav.isMember("include-directories")) {
    if (!JsonIsStringArray(lav["include-directories"])) {
      state->AddErrorAtValue(
        "'include-directories' must be an array of strings",
        &lav["include-directories"]);
      return false;
    }
    for (auto const& s : lav["include-directories"]) {
      out.IncludeDirectories.push_back(s.asString());
    }
  }

  if (lav.isMember("system-include-directories")) {
    if (!JsonIsStringArray(lav["system-include-directories"])) {
      state->AddErrorAtValue(
        "'system-include-directories' must be an array of strings",
        &lav["system-include-directories"]);
      return false;
    }
    for (auto const& s : lav["system-include-directories"]) {
      out.SystemIncludeDirectories.push_back(s.asString());
    }
  }

  if (lav.isMember("definitions")) {
    if (!lav["definitions"].isArray()) {
      state->AddErrorAtValue("'definitions' must be an array",
                             &lav["definitions"]);
      return false;
    }
    for (Json::Value& dval : lav["definitions"]) {
      out.Definitions.emplace_back();
      if (!ParsePreprocessorDefine(dval, out.Definitions.back(), state)) {
        return false;
      }
    }
  }

  if (lav.isMember("vendor")) {
    if (!ParseCMakeLocalArgumentsVendor(lav["vendor"], out, state)) {
      return false;
    }
  }

  return true;
}

bool ParseModule(Json::Value& mval, cmCxxModuleMetadata::ModuleData& mod,
                 cmJSONState* state)
{
  if (!mval.isObject()) {
    state->AddErrorAtValue("each entry in 'modules' must be an object", &mval);
    return false;
  }

  if (!mval.isMember("logical-name") || !mval["logical-name"].isString() ||
      mval["logical-name"].asString().empty()) {
    state->AddErrorAtValue(
      "module entries require a non-empty 'logical-name' string",
      &mval["logical-name"]);
    return false;
  }
  mod.LogicalName = mval["logical-name"].asString();

  if (!mval.isMember("source-path") || !mval["source-path"].isString() ||
      mval["source-path"].asString().empty()) {
    state->AddErrorAtValue(
      "module entries require a non-empty 'source-path' string",
      &mval["source-path"]);
    return false;
  }
  mod.SourcePath = mval["source-path"].asString();

  if (mval.isMember("is-interface")) {
    if (!mval["is-interface"].isBool()) {
      state->AddErrorAtValue("'is-interface' must be boolean",
                             &mval["is-interface"]);
      return false;
    }
    mod.IsInterface = mval["is-interface"].asBool();
  } else {
    mod.IsInterface = true;
  }

  if (mval.isMember("is-std-library")) {
    if (!mval["is-std-library"].isBool()) {
      state->AddErrorAtValue("'is-std-library' must be boolean",
                             &mval["is-std-library"]);
      return false;
    }
    mod.IsStdLibrary = mval["is-std-library"].asBool();
  } else {
    mod.IsStdLibrary = false;
  }

  if (mval.isMember("local-arguments")) {
    mod.LocalArguments.emplace();
    if (!ParseLocalArguments(mval["local-arguments"], *mod.LocalArguments,
                             state)) {
      return false;
    }
  }

  return true;
}

bool ParseRoot(Json::Value& root, cmCxxModuleMetadata& meta,
               cmJSONState* state)
{
  if (!root.isMember("version") || !root["version"].isInt()) {
    state->AddErrorAtValue(
      "Top-level member 'version' is required and must be an integer", &root);
    return false;
  }
  meta.Version = root["version"].asInt();

  if (root.isMember("revision")) {
    if (!root["revision"].isInt()) {
      state->AddErrorAtValue("'revision' must be an integer",
                             &root["revision"]);
      return false;
    }
    meta.Revision = root["revision"].asInt();
  }

  if (meta.Version != 1) {
    state->AddErrorAtValue(cmStrCat("Module manifest version number, '",
                                    meta.Version, '.', meta.Revision,
                                    "' is newer than max supported (1.1)"),
                           &root);
    return false;
  }

  if (root.isMember("modules")) {
    if (!root["modules"].isArray()) {
      state->AddErrorAtValue("'modules' must be an array", &root["modules"]);
      return false;
    }
    for (Json::Value& mval : root["modules"]) {
      meta.Modules.emplace_back();
      if (!ParseModule(mval, meta.Modules.back(), state)) {
        return false;
      }
    }
  }

  return true;
}

} // namespace

cmCxxModuleMetadata::ParseResult cmCxxModuleMetadata::LoadFromFile(
  std::string const& path)
{
  ParseResult res;

  Json::Value root;
  cmJSONState parseState(path, &root);
  if (!parseState.errors.empty()) {
    res.Error = parseState.GetErrorMessage();
    return res;
  }

  cmCxxModuleMetadata meta;
  if (!ParseRoot(root, meta, &parseState)) {
    res.Error = parseState.GetErrorMessage();
    return res;
  }

  meta.MetadataFilePath = path;
  res.Meta = std::move(meta);
  return res;
}

namespace {

Json::Value SerializePreprocessorDefine(
  cmCxxModuleMetadata::PreprocessorDefineData const& d)
{
  Json::Value dv(Json::objectValue);
  dv["name"] = d.Name;
  if (d.Value) {
    dv["value"] = *d.Value;
  }
  if (d.Undef) {
    dv["undef"] = d.Undef;
  }
  return dv;
}

Json::Value SerializeCMakeLocalArgumentsVendor(
  cmCxxModuleMetadata::LocalArgumentsData const& la)
{
  Json::Value vend(Json::objectValue);

  if (!la.CompileOptions.empty()) {
    Json::Value& opts = vend["compile-options"] = Json::arrayValue;
    for (auto const& s : la.CompileOptions) {
      opts.append(s);
    }
  }

  if (!la.CompileFeatures.empty()) {
    Json::Value& feats = vend["compile-features"] = Json::arrayValue;
    for (auto const& s : la.CompileFeatures) {
      feats.append(s);
    }
  }

  return vend;
}

Json::Value SerializeLocalArguments(
  cmCxxModuleMetadata::LocalArgumentsData const& la)
{
  Json::Value lav(Json::objectValue);

  if (!la.IncludeDirectories.empty()) {
    Json::Value& inc = lav["include-directories"] = Json::arrayValue;
    for (auto const& s : la.IncludeDirectories) {
      inc.append(s);
    }
  }

  if (!la.SystemIncludeDirectories.empty()) {
    Json::Value& sinc = lav["system-include-directories"] = Json::arrayValue;
    for (auto const& s : la.SystemIncludeDirectories) {
      sinc.append(s);
    }
  }

  if (!la.Definitions.empty()) {
    Json::Value& defs = lav["definitions"] = Json::arrayValue;
    for (auto const& d : la.Definitions) {
      defs.append(SerializePreprocessorDefine(d));
    }
  }

  Json::Value vend = SerializeCMakeLocalArgumentsVendor(la);
  if (!vend.empty()) {
    Json::Value& cmvend = lav["vendor"] = Json::objectValue;
    cmvend["cmake"] = std::move(vend);
  }

  return lav;
}

Json::Value SerializeModule(std::string& manifestRoot,
                            cmCxxModuleMetadata::ModuleData const& m)
{
  Json::Value mv(Json::objectValue);
  mv["logical-name"] = m.LogicalName;
  if (cmSystemTools::FileIsFullPath(m.SourcePath)) {
    mv["source-path"] = m.SourcePath;
  } else {
    mv["source-path"] = cmSystemTools::ForceToRelativePath(
      manifestRoot, cmStrCat('/', m.SourcePath));
  }
  mv["is-interface"] = m.IsInterface;
  mv["is-std-library"] = m.IsStdLibrary;

  if (m.LocalArguments) {
    mv["local-arguments"] = SerializeLocalArguments(*m.LocalArguments);
  }

  return mv;
}

} // namespace

Json::Value cmCxxModuleMetadata::ToJsonValue(cmCxxModuleMetadata const& meta)
{
  Json::Value root(Json::objectValue);

  root["version"] = meta.Version;
  root["revision"] = meta.Revision;

  Json::Value& modules = root["modules"] = Json::arrayValue;
  std::string manifestRoot =
    cmSystemTools::GetFilenamePath(meta.MetadataFilePath);

  if (!cmSystemTools::FileIsFullPath(meta.MetadataFilePath)) {
    manifestRoot = cmStrCat('/', manifestRoot);
  }

  for (auto const& m : meta.Modules) {
    modules.append(SerializeModule(manifestRoot, m));
  }

  return root;
}

cmCxxModuleMetadata::SaveResult cmCxxModuleMetadata::SaveToFile(
  std::string const& path, cmCxxModuleMetadata const& meta)
{
  SaveResult st;

  cmGeneratedFileStream ofs(path);
  if (!ofs.is_open()) {
    st.Error = "Unable to open temp file for writing";
    return st;
  }

  Json::StreamWriterBuilder wbuilder;
  wbuilder["indentation"] = "  ";
  ofs << Json::writeString(wbuilder, ToJsonValue(meta));

  ofs.Close();

  if (!ofs.good()) {
    st.Error = cmStrCat("Write failed for file: "_s, path);
    return st;
  }

  st.Ok = true;
  return st;
}

namespace {

struct MetaDataProperties
{
  std::string MetadataDir;
  std::set<cm::string_view> AllCompileFeatures;
  std::set<cm::string_view> AllCompileOptions;
  std::set<std::string> AllIncludeDirectories;
  std::set<std::string> AllCompileDefinitions;
  std::set<std::string> BaseDirs;
  std::set<std::string> Sources;

  std::string NormalizePath(std::string const& in) const
  {
    std::string out = in;
    if (!cmSystemTools::FileIsFullPath(in)) {
      out = cmStrCat(MetadataDir, '/', in);
    }
    return cmSystemTools::CollapseFullPath(out);
  }
};

MetaDataProperties CollectMetaProperties(cmCxxModuleMetadata const& meta)
{
  MetaDataProperties props;

  props.MetadataDir = cmSystemTools::GetFilenamePath(meta.MetadataFilePath);

#ifndef _WIN32
  props.BaseDirs.insert("/");
#endif

  for (auto const& module : meta.Modules) {
    std::string sourcePath = props.NormalizePath(module.SourcePath);
    props.Sources.insert(sourcePath);

#ifdef _WIN32
    std::string root;
    cmSystemTools::SplitPathRootComponent(sourcePath, &root);
    props.BaseDirs.insert(root);
#endif

    if (module.LocalArguments) {
      for (auto const& incDir : module.LocalArguments->IncludeDirectories) {
        props.AllIncludeDirectories.emplace(props.NormalizePath(incDir));
      }
      for (auto const& sysIncDir :
           module.LocalArguments->SystemIncludeDirectories) {
        props.AllIncludeDirectories.emplace(props.NormalizePath(sysIncDir));
      }
      for (auto const& opt : module.LocalArguments->CompileOptions) {
        props.AllCompileOptions.emplace(opt);
      }
      for (auto const& opt : module.LocalArguments->CompileFeatures) {
        props.AllCompileFeatures.emplace(opt);
      }

      for (auto const& def : module.LocalArguments->Definitions) {
        if (!def.Undef) {
          if (def.Value) {
            props.AllCompileDefinitions.emplace(
              cmStrCat(def.Name, "="_s, *def.Value));
          } else {
            props.AllCompileDefinitions.emplace(def.Name);
          }
        }
      }
    }
  }

  return props;
}

void PopulateFileSet(cmTarget& target, MetaDataProperties const& props)
{
  auto fileSet =
    target.GetOrCreateFileSet(std::string{ cm::FileSetMetadata::CXX_MODULES },
                              std::string{ cm::FileSetMetadata::CXX_MODULES },
                              cm::FileSetMetadata::Visibility::Public);

  for (auto const& source : props.Sources) {
    fileSet.first->AddFileEntry(source);
  }

  for (auto const& baseDir : props.BaseDirs) {
    fileSet.first->AddDirectoryEntry(baseDir);
  }
}

void PopulateLocalTarget(cmTarget& target, MetaDataProperties const& props)
{
  if (!props.AllIncludeDirectories.empty()) {
    target.AppendProperty("INCLUDE_DIRECTORIES",
                          cmJoin(props.AllIncludeDirectories, ";"));
  }

  if (!props.AllCompileDefinitions.empty()) {
    target.AppendProperty("COMPILE_DEFINITIONS",
                          cmJoin(props.AllCompileDefinitions, ";"));
  }

  if (!props.AllCompileOptions.empty()) {
    target.AppendProperty("COMPILE_OPTIONS",
                          cmJoin(props.AllCompileOptions, ";"));
  }

  if (!props.AllCompileFeatures.empty()) {
    target.AppendProperty("COMPILE_FEATURES",
                          cmJoin(props.AllCompileFeatures, ";"));
  }
}

void PopulateImportedTarget(cmTarget& target, MetaDataProperties const& props,
                            cmCxxModuleMetadata const& meta,
                            std::vector<std::string> const& configs)
{
  if (!props.AllIncludeDirectories.empty()) {
    target.SetProperty("IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES",
                       cmJoin(props.AllIncludeDirectories, ";"));
  }

  if (!props.AllCompileDefinitions.empty()) {
    target.SetProperty("IMPORTED_CXX_MODULES_COMPILE_DEFINITIONS",
                       cmJoin(props.AllCompileDefinitions, ";"));
  }

  if (!props.AllCompileOptions.empty()) {
    target.SetProperty("IMPORTED_CXX_MODULES_COMPILE_OPTIONS",
                       cmJoin(props.AllCompileOptions, ";"));
  }

  if (!props.AllCompileFeatures.empty()) {
    target.SetProperty("IMPORTED_CXX_MODULES_COMPILE_FEATURES",
                       cmJoin(props.AllCompileFeatures, ";"));
  }

  for (auto const& config : configs) {
    std::vector<std::string> moduleList;
    for (auto const& module : meta.Modules) {
      if (module.IsInterface) {
        moduleList.push_back(cmStrCat(module.LogicalName, "="_s,
                                      props.NormalizePath(module.SourcePath)));
      }
    }

    if (!moduleList.empty()) {
      std::string upperConfig = cmSystemTools::UpperCase(config);
      std::string propertyName =
        cmStrCat("IMPORTED_CXX_MODULES_"_s, upperConfig);
      target.SetProperty(propertyName, cmJoin(moduleList, ";"));
    }
  }
}

} // namespace

void cmCxxModuleMetadata::PopulateTarget(
  cmTarget& target, cmCxxModuleMetadata const& meta,
  std::vector<std::string> const& configs)
{
  auto props = CollectMetaProperties(meta);
  PopulateFileSet(target, props);

  if (target.IsImported()) {
    PopulateImportedTarget(target, props, meta, configs);
  } else {
    PopulateLocalTarget(target, props);
  }
}
