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

#include <cstdlib>
#include <set>
#include <utility>

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

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

#include "cmsys/FStream.hxx"

#include "cmComputeLinkInformation.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

namespace {

std::string PlaceholderName = "<__CMAKE_UNKNOWN>";

}

cmBuildDatabase::cmBuildDatabase() = default;
cmBuildDatabase::cmBuildDatabase(cmBuildDatabase const&) = default;
cmBuildDatabase::~cmBuildDatabase() = default;

cmBuildDatabase::LookupTable cmBuildDatabase::GenerateLookupTable()
{
  LookupTable lut;

  for (auto& Set_ : this->Sets) {
    for (auto& TranslationUnit_ : Set_.TranslationUnits) {
      // This table is from source path to TU instance. This is fine because a
      // single target (where this is used) cannot contain the same source file
      // multiple times.
      lut[TranslationUnit_.Source] = &TranslationUnit_;
    }
  }

  return lut;
}

bool cmBuildDatabase::HasPlaceholderNames() const
{
  for (auto const& Set_ : this->Sets) {
    for (auto const& TranslationUnit_ : Set_.TranslationUnits) {
      for (auto const& provide : TranslationUnit_.Provides) {
        if (provide.first == PlaceholderName) {
          return true;
        }
        if (provide.second == PlaceholderName) {
          return true;
        }
      }
    }
  }

  return false;
}

void cmBuildDatabase::Write(std::string const& path) const
{
  Json::Value mcdb = Json::objectValue;

  mcdb["version"] = 1;
  mcdb["revision"] = 0;

  Json::Value& sets = mcdb["sets"] = Json::arrayValue;

  for (auto const& Set_ : this->Sets) {
    Json::Value set = Json::objectValue;

    set["name"] = Set_.Name;
    set["family-name"] = Set_.FamilyName;

    Json::Value& visible_sets = set["visible-sets"] = Json::arrayValue;
    for (auto const& VisibleSet : Set_.VisibleSets) {
      visible_sets.append(VisibleSet);
    }

    Json::Value& tus = set["translation-units"] = Json::arrayValue;
    for (auto const& TranslationUnit_ : Set_.TranslationUnits) {
      Json::Value tu = Json::objectValue;

      if (!TranslationUnit_.WorkDirectory.empty()) {
        tu["work-directory"] = TranslationUnit_.WorkDirectory;
      }
      tu["source"] = TranslationUnit_.Source;
      if (TranslationUnit_.Object) {
        tu["object"] = *TranslationUnit_.Object;
      }
      tu["private"] = TranslationUnit_.Private;

      Json::Value& reqs = tu["requires"] = Json::arrayValue;
      for (auto const& Require : TranslationUnit_.Requires) {
        reqs.append(Require);
      }

      Json::Value& provides = tu["provides"] = Json::objectValue;
      for (auto const& Provide : TranslationUnit_.Provides) {
        provides[Provide.first] = Provide.second;
      }

      Json::Value& baseline_arguments = tu["baseline-arguments"] =
        Json::arrayValue;
      for (auto const& BaselineArgument : TranslationUnit_.BaselineArguments) {
        baseline_arguments.append(BaselineArgument);
      }

      Json::Value& local_arguments = tu["local-arguments"] = Json::arrayValue;
      for (auto const& LocalArgument : TranslationUnit_.LocalArguments) {
        local_arguments.append(LocalArgument);
      }

      Json::Value& arguments = tu["arguments"] = Json::arrayValue;
      for (auto const& Argument : TranslationUnit_.Arguments) {
        arguments.append(Argument);
      }

      tus.append(tu);
    }

    sets.append(set);
  }

  cmGeneratedFileStream mcdbf(path);
  mcdbf << mcdb;
}

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

  return true;
}

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

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

std::unique_ptr<cmBuildDatabase> cmBuildDatabase::Load(std::string const& path)
{
  Json::Value mcdb;
  {
    cmsys::ifstream mcdbf(path.c_str(), std::ios::in | std::ios::binary);
    Json::Reader reader;
    if (!reader.parse(mcdbf, mcdb, false)) {
      cmSystemTools::Error(
        cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                 reader.getFormattedErrorMessages()));
      return {};
    }
  }

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

  auto db = cm::make_unique<cmBuildDatabase>();

  Json::Value const& sets = mcdb["sets"];
  if (sets.isArray()) {
    for (auto const& set : sets) {
      Set Set_;

      Json::Value const& name = set["name"];
      if (!name.isString()) {
        cmSystemTools::Error(
          cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                   ": name is not a string"));
        return {};
      }
      Set_.Name = name.asString();

      Json::Value const& family_name = set["family-name"];
      if (!family_name.isString()) {
        cmSystemTools::Error(
          cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                   ": family-name is not a string"));
        return {};
      }
      Set_.FamilyName = family_name.asString();

      Json::Value const& visible_sets = set["visible-sets"];
      if (!visible_sets.isArray()) {
        cmSystemTools::Error(
          cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                   ": visible-sets is not an array"));
        return {};
      }
      for (auto const& visible_set : visible_sets) {
        if (!visible_set.isString()) {
          cmSystemTools::Error(
            cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                     ": a visible-sets item is not a string"));
          return {};
        }

        Set_.VisibleSets.emplace_back(visible_set.asString());
      }

      Json::Value const& translation_units = set["translation-units"];
      if (!translation_units.isArray()) {
        cmSystemTools::Error(
          cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                   ": translation-units is not an array"));
        return {};
      }
      for (auto const& translation_unit : translation_units) {
        if (!translation_unit.isObject()) {
          cmSystemTools::Error(
            cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                     ": a translation-units item is not an object"));
          return {};
        }

        TranslationUnit TranslationUnit_;

        cm::optional<std::string> work_directory;
        Json::Value const& workdir = translation_unit["work-directory"];
        if (workdir.isString()) {
          PARSE_BLOB(workdir, TranslationUnit_.WorkDirectory);
          work_directory = TranslationUnit_.WorkDirectory;
        } else if (!workdir.isNull()) {
          cmSystemTools::Error(
            cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                     ": work-directory is not a string"));
          return {};
        }

        Json::Value const& source = translation_unit["source"];
        PARSE_FILENAME(source, TranslationUnit_.Source, true);

        if (translation_unit.isMember("object")) {
          Json::Value const& object = translation_unit["object"];
          if (!object.isNull()) {
            TranslationUnit_.Object = "";
            PARSE_FILENAME(object, *TranslationUnit_.Object, false);
          }
        }

        if (translation_unit.isMember("private")) {
          Json::Value const& priv = translation_unit["private"];
          if (!priv.isBool()) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                       ": private is not a boolean"));
            return {};
          }
          TranslationUnit_.Private = priv.asBool();
        }

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

          for (auto const& require : reqs) {
            if (!require.isString()) {
              cmSystemTools::Error(
                cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                         ": a requires item is not a string"));
              return {};
            }

            TranslationUnit_.Requires.emplace_back(require.asString());
          }
        }

        if (translation_unit.isMember("provides")) {
          Json::Value const& provides = translation_unit["provides"];
          if (!provides.isObject()) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                       ": provides is not an object"));
            return {};
          }

          for (auto i = provides.begin(); i != provides.end(); ++i) {
            if (!i->isString()) {
              cmSystemTools::Error(
                cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                         ": a provides value is not a string"));
              return {};
            }

            TranslationUnit_.Provides[i.key().asString()] = i->asString();
          }
        }

        if (translation_unit.isMember("baseline-arguments")) {
          Json::Value const& baseline_arguments =
            translation_unit["baseline-arguments"];
          if (!baseline_arguments.isArray()) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                       ": baseline_arguments is not an array"));
            return {};
          }

          for (auto const& baseline_argument : baseline_arguments) {
            if (baseline_argument.isString()) {
              TranslationUnit_.BaselineArguments.emplace_back(
                baseline_argument.asString());
            } else {
              cmSystemTools::Error(
                cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                         ": a baseline argument is not a string"));
              return {};
            }
          }
        }

        if (translation_unit.isMember("local-arguments")) {
          Json::Value const& local_arguments =
            translation_unit["local-arguments"];
          if (!local_arguments.isArray()) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                       ": local_arguments is not an array"));
            return {};
          }

          for (auto const& local_argument : local_arguments) {
            if (local_argument.isString()) {
              TranslationUnit_.LocalArguments.emplace_back(
                local_argument.asString());
            } else {
              cmSystemTools::Error(
                cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                         ": a local argument is not a string"));
              return {};
            }
          }
        }

        if (translation_unit.isMember("arguments")) {
          Json::Value const& arguments = translation_unit["arguments"];
          if (!arguments.isArray()) {
            cmSystemTools::Error(
              cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                       ": arguments is not an array"));
            return {};
          }

          for (auto const& argument : arguments) {
            if (argument.isString()) {
              TranslationUnit_.Arguments.emplace_back(argument.asString());
            } else {
              cmSystemTools::Error(
                cmStrCat("-E cmake_module_compile_db failed to parse ", path,
                         ": an argument is not a string"));
              return {};
            }
          }
        }

        Set_.TranslationUnits.emplace_back(std::move(TranslationUnit_));
      }

      db->Sets.emplace_back(std::move(Set_));
    }
  }

  return db;
}

cmBuildDatabase cmBuildDatabase::Merge(
  std::vector<cmBuildDatabase> const& components)
{
  cmBuildDatabase db;

  for (auto const& component : components) {
    db.Sets.insert(db.Sets.end(), component.Sets.begin(),
                   component.Sets.end());
  }

  return db;
}

cmBuildDatabase cmBuildDatabase::ForTarget(cmGeneratorTarget* gt,
                                           std::string const& config)
{
  cmBuildDatabase db;

  Set set;
  set.Name = cmStrCat(gt->GetName(), '@', config);
  set.FamilyName = gt->GetFamilyName();
  if (auto* cli = gt->GetLinkInformation(config)) {
    std::set<cmGeneratorTarget const*> emitted;
    std::vector<cmGeneratorTarget const*> targets;
    for (auto const& item : cli->GetItems()) {
      auto const* linkee = item.Target;
      if (linkee && linkee->HaveCxx20ModuleSources() &&
          !linkee->IsImported() && emitted.insert(linkee).second) {
        set.VisibleSets.push_back(cmStrCat(linkee->GetName(), '@', config));
      }
    }
  }

  for (auto const& sfbt : gt->GetSourceFiles(config)) {
    auto const* sf = sfbt.Value;

    bool isCXXModule = false;
    bool isPrivate = true;
    if (sf->GetLanguage() == "CXX"_s) {
      auto const* fs = gt->GetFileSetForSource(config, sf);
      if (fs && fs->GetType() == "CXX_MODULES"_s) {
        isCXXModule = true;
        isPrivate = !cmFileSetVisibilityIsForInterface(fs->GetVisibility());
      }
    }

    TranslationUnit tu;

    // FIXME: Makefiles will want this to be the current working directory.
    tu.WorkDirectory = gt->GetLocalGenerator()->GetBinaryDirectory();
    tu.Source = sf->GetFullPath();
    if (!gt->IsSynthetic()) {
      auto* gg = gt->GetGlobalGenerator();
      std::string const objectDir = gg->ConvertToOutputPath(
        cmStrCat(gt->GetSupportDirectory(), gg->GetConfigDirectory(config)));
      std::string const objectFileName = gt->GetObjectName(sf);
      tu.Object = cmStrCat(objectDir, '/', objectFileName);
    }
    if (isCXXModule) {
      tu.Provides[PlaceholderName] = PlaceholderName;
    }

    cmGeneratorTarget::ClassifiedFlags classifiedFlags =
      gt->GetClassifiedFlagsForSource(sf, config);
    for (auto const& classifiedFlag : classifiedFlags) {
      if (classifiedFlag.Classification ==
          cmGeneratorTarget::FlagClassification::BaselineFlag) {
        tu.BaselineArguments.push_back(classifiedFlag.Flag);
        tu.LocalArguments.push_back(classifiedFlag.Flag);
      } else if (classifiedFlag.Classification ==
                 cmGeneratorTarget::FlagClassification::PrivateFlag) {
        tu.LocalArguments.push_back(classifiedFlag.Flag);
      }
      tu.Arguments.push_back(classifiedFlag.Flag);
    }
    tu.Private = isPrivate;

    set.TranslationUnits.emplace_back(std::move(tu));
  }

  db.Sets.emplace_back(std::move(set));

  return db;
}

int cmcmd_cmake_module_compile_db(
  std::vector<std::string>::const_iterator argBeg,
  std::vector<std::string>::const_iterator argEnd)
{
  std::string const* command = nullptr;
  std::string const* output = nullptr;
  std::vector<std::string const*> inputs;

  bool next_is_output = false;
  for (auto i = argBeg; i != argEnd; ++i) {
    // The first argument is always the command.
    if (!command) {
      command = &(*i);
      continue;
    }

    if (*i == "-o"_s) {
      next_is_output = true;
      continue;
    }
    if (next_is_output) {
      if (output) {
        cmSystemTools::Error(
          "-E cmake_module_compile_db only supports one output file");
        return EXIT_FAILURE;
      }

      output = &(*i);
      next_is_output = false;
      continue;
    }

    inputs.emplace_back(&(*i));
  }

  if (!command) {
    cmSystemTools::Error("-E cmake_module_compile_db requires a subcommand");
    return EXIT_FAILURE;
  }

  int ret = EXIT_SUCCESS;

  if (*command == "verify"_s) {
    if (output) {
      cmSystemTools::Error(
        "-E cmake_module_compile_db verify does not support an output");
      return EXIT_FAILURE;
    }

    for (auto const* i : inputs) {
      auto db = cmBuildDatabase::Load(*i);
      if (!db) {
        cmSystemTools::Error(cmStrCat("failed to verify ", *i));
        ret = EXIT_FAILURE;
      }
    }
  } else if (*command == "merge"_s) {
    if (!output) {
      cmSystemTools::Error(
        "-E cmake_module_compile_db verify requires an output");
      return EXIT_FAILURE;
    }

    std::vector<cmBuildDatabase> dbs;

    for (auto const* i : inputs) {
      auto db = cmBuildDatabase::Load(*i);
      if (!db) {
        cmSystemTools::Error(cmStrCat("failed to read ", *i));
        return EXIT_FAILURE;
      }

      dbs.emplace_back(std::move(*db));
    }

    auto db = cmBuildDatabase::Merge(dbs);
    db.Write(*output);
  } else {
    cmSystemTools::Error(
      cmStrCat("-E cmake_module_compile_db unknown subcommand ", *command));
    return EXIT_FAILURE;
  }

  return ret;
}
