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

#include <cassert>
#include <cstddef>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

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

#include "cmScanDepFormat.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"

cm::optional<std::string> CxxModuleLocations::BmiGeneratorPathForModule(
  std::string const& logical_name) const
{
  if (auto l = this->BmiLocationForModule(logical_name)) {
    return this->PathForGenerator(*l);
  }
  return {};
}

namespace {

std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
                                   cmScanDepInfo const& obj)
{
  std::stringstream mm;

  // Documented in GCC's documentation. The format is a series of
  // lines with a module name and the associated filename separated
  // by spaces. The first line may use `$root` as the module name
  // to specify a "repository root". That is used to anchor any
  // relative paths present in the file (CMake should never
  // generate any).

  // Write the root directory to use for module paths.
  mm << "$root " << loc.RootDirectory << "\n";

  for (auto const& p : obj.Provides) {
    if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
      mm << p.LogicalName << ' ' << *bmi_loc << '\n';
    }
  }
  for (auto const& r : obj.Requires) {
    if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
      mm << r.LogicalName << ' ' << *bmi_loc << '\n';
    }
  }

  return mm.str();
}

std::string CxxModuleMapContentMsvc(CxxModuleLocations const& loc,
                                    cmScanDepInfo const& obj,
                                    CxxModuleUsage const& usages)
{
  std::stringstream mm;

  // A response file of `-reference NAME=PATH` arguments.

  // MSVC's command line only supports a single output. If more than one is
  // expected, we cannot make a useful module map file.
  if (obj.Provides.size() > 1) {
    return {};
  }

  auto flag_for_method = [](LookupMethod method) -> cm::static_string_view {
    switch (method) {
      case LookupMethod::ByName:
        return "-reference"_s;
      case LookupMethod::IncludeAngle:
        return "-headerUnit:angle"_s;
      case LookupMethod::IncludeQuote:
        return "-headerUnit:quote"_s;
    }
    assert(false && "unsupported lookup method");
    return ""_s;
  };

  for (auto const& p : obj.Provides) {
    if (p.IsInterface) {
      mm << "-interface\n";
    } else {
      mm << "-internalPartition\n";
    }

    if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
      mm << "-ifcOutput " << *bmi_loc << '\n';
    }
  }

  std::set<std::string> transitive_usage_directs;
  std::set<std::string> transitive_usage_names;

  for (auto const& r : obj.Requires) {
    if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
      auto flag = flag_for_method(r.Method);

      mm << flag << ' ' << r.LogicalName << '=' << *bmi_loc << "\n";
      transitive_usage_directs.insert(r.LogicalName);

      // Insert transitive usages.
      auto transitive_usages = usages.Usage.find(r.LogicalName);
      if (transitive_usages != usages.Usage.end()) {
        transitive_usage_names.insert(transitive_usages->second.begin(),
                                      transitive_usages->second.end());
      }
    }
  }

  for (auto const& transitive_name : transitive_usage_names) {
    if (transitive_usage_directs.count(transitive_name)) {
      continue;
    }

    auto module_ref = usages.Reference.find(transitive_name);
    if (module_ref != usages.Reference.end()) {
      auto flag = flag_for_method(module_ref->second.Method);
      mm << flag << ' ' << transitive_name << '=' << module_ref->second.Path
         << "\n";
    }
  }

  return mm.str();
}
}

bool CxxModuleUsage::AddReference(std::string const& logical,
                                  std::string const& loc, LookupMethod method)
{
  auto r = this->Reference.find(logical);
  if (r != this->Reference.end()) {
    auto& ref = r->second;

    if (ref.Path == loc && ref.Method == method) {
      return true;
    }

    auto method_name = [](LookupMethod m) -> cm::static_string_view {
      switch (m) {
        case LookupMethod::ByName:
          return "by-name"_s;
        case LookupMethod::IncludeAngle:
          return "include-angle"_s;
        case LookupMethod::IncludeQuote:
          return "include-quote"_s;
      }
      assert(false && "unsupported lookup method");
      return ""_s;
    };

    cmSystemTools::Error(cmStrCat("Disagreement of the location of the '",
                                  logical,
                                  "' module. "
                                  "Location A: '",
                                  ref.Path, "' via ", method_name(ref.Method),
                                  "; "
                                  "Location B: '",
                                  loc, "' via ", method_name(method), "."));
    return false;
  }

  auto& ref = this->Reference[logical];
  ref.Path = loc;
  ref.Method = method;

  return true;
}

cm::static_string_view CxxModuleMapExtension(
  cm::optional<CxxModuleMapFormat> format)
{
  if (format) {
    switch (*format) {
      case CxxModuleMapFormat::Gcc:
        return ".gcm"_s;
      case CxxModuleMapFormat::Msvc:
        return ".ifc"_s;
    }
  }

  return ".bmi"_s;
}

std::set<std::string> CxxModuleUsageSeed(
  CxxModuleLocations const& loc, std::vector<cmScanDepInfo> const& objects,
  CxxModuleUsage& usages)
{
  // Track inner usages to populate usages from internal bits.
  //
  // This is a map of modules that required some other module that was not
  // found to those that were not found.
  std::map<std::string, std::set<std::string>> internal_usages;
  std::set<std::string> unresolved;

  for (cmScanDepInfo const& object : objects) {
    // Add references for each of the provided modules.
    for (auto const& p : object.Provides) {
      if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
        // XXX(cxx-modules): How to support header units?
        usages.AddReference(p.LogicalName, loc.PathForGenerator(*bmi_loc),
                            LookupMethod::ByName);
      }
    }

    // For each requires, pull in what is required.
    for (auto const& r : object.Requires) {
      // Find transitive usages.
      auto transitive_usages = usages.Usage.find(r.LogicalName);
      // Find the required name in the current target.
      auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);

      for (auto const& p : object.Provides) {
        auto& this_usages = usages.Usage[p.LogicalName];

        // Add the direct usage.
        this_usages.insert(r.LogicalName);

        // Add the transitive usage.
        if (transitive_usages != usages.Usage.end()) {
          this_usages.insert(transitive_usages->second.begin(),
                             transitive_usages->second.end());
        } else if (bmi_loc) {
          // Mark that we need to update transitive usages later.
          internal_usages[p.LogicalName].insert(r.LogicalName);
        }
      }

      if (bmi_loc) {
        usages.AddReference(r.LogicalName, loc.PathForGenerator(*bmi_loc),
                            r.Method);
      }
    }
  }

  // While we have internal usages to manage.
  while (!internal_usages.empty()) {
    size_t starting_size = internal_usages.size();

    // For each internal usage.
    for (auto usage = internal_usages.begin(); usage != internal_usages.end();
         /* see end of loop */) {
      auto& this_usages = usages.Usage[usage->first];

      for (auto use = usage->second.begin(); use != usage->second.end();
           /* see end of loop */) {
        // Check if this required module uses other internal modules; defer
        // if so.
        if (internal_usages.count(*use)) {
          // Advance the iterator.
          ++use;
          continue;
        }

        auto transitive_usages = usages.Usage.find(*use);
        if (transitive_usages != usages.Usage.end()) {
          this_usages.insert(transitive_usages->second.begin(),
                             transitive_usages->second.end());
        }

        // Remove the entry and advance the iterator.
        use = usage->second.erase(use);
      }

      // Erase the entry if it doesn't have any remaining usages.
      if (usage->second.empty()) {
        usage = internal_usages.erase(usage);
      } else {
        ++usage;
      }
    }

    // Check that at least one usage was resolved.
    if (starting_size == internal_usages.size()) {
      // Nothing could be resolved this loop; we have a cycle, so record the
      // cycle and exit.
      for (auto const& usage : internal_usages) {
        unresolved.insert(usage.first);
      }
      break;
    }
  }

  return unresolved;
}

std::string CxxModuleMapContent(CxxModuleMapFormat format,
                                CxxModuleLocations const& loc,
                                cmScanDepInfo const& obj,
                                CxxModuleUsage const& usages)
{
  switch (format) {
    case CxxModuleMapFormat::Gcc:
      return CxxModuleMapContentGcc(loc, obj);
    case CxxModuleMapFormat::Msvc:
      return CxxModuleMapContentMsvc(loc, obj, usages);
  }

  assert(false);
  return {};
}
