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

#include <memory>
#include <utility>

#include <cmext/algorithm>

#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmProperty.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"

class cmake;

cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm)
  : cmGlobalGenerator(cm)
{
}

cmGlobalCommonGenerator::~cmGlobalCommonGenerator() = default;

std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
cmGlobalCommonGenerator::ComputeDirectoryTargets() const
{
  std::map<std::string, DirectoryTarget> dirTargets;
  for (const auto& lg : this->LocalGenerators) {
    std::string const& currentBinaryDir(
      lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
    DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
    dirTarget.LG = lg.get();
    const std::vector<std::string>& configs =
      lg->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);

    // The directory-level rule should depend on the target-level rules
    // for all targets in the directory.
    for (const auto& gt : lg->GetGeneratorTargets()) {
      cmStateEnums::TargetType const type = gt->GetType();
      if (type == cmStateEnums::GLOBAL_TARGET || !gt->IsInBuildSystem()) {
        continue;
      }
      DirectoryTarget::Target t;
      t.GT = gt.get();
      const std::string EXCLUDE_FROM_ALL("EXCLUDE_FROM_ALL");
      if (cmProp exclude = gt->GetProperty(EXCLUDE_FROM_ALL)) {
        for (const std::string& config : configs) {
          cmGeneratorExpressionInterpreter genexInterpreter(lg.get(), config,
                                                            gt.get());
          if (cmIsOn(genexInterpreter.Evaluate(*exclude, EXCLUDE_FROM_ALL))) {
            // This target has been explicitly excluded.
            t.ExcludedFromAllInConfigs.push_back(config);
          }
        }

        if (t.ExcludedFromAllInConfigs.empty()) {
          // This target has been explicitly un-excluded.  The directory-level
          // rule for every directory between this and the root should depend
          // on the target-level rule for this target.
          for (cmStateSnapshot dir =
                 lg->GetStateSnapshot().GetBuildsystemDirectoryParent();
               dir.IsValid(); dir = dir.GetBuildsystemDirectoryParent()) {
            std::string const& d = dir.GetDirectory().GetCurrentBinary();
            dirTargets[d].Targets.emplace_back(t);
          }
        }
      }
      dirTarget.Targets.emplace_back(t);
    }

    // The directory-level rule should depend on the directory-level
    // rules of the subdirectories.
    for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) {
      DirectoryTarget::Dir d;
      d.Path = state.GetDirectory().GetCurrentBinary();
      d.ExcludeFromAll =
        state.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL");
      dirTarget.Children.emplace_back(std::move(d));
    }
  }

  return dirTargets;
}

bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig(
  const DirectoryTarget::Target& t, const std::string& config)
{
  if (this->IsMultiConfig()) {
    return cm::contains(t.ExcludedFromAllInConfigs, config);
  }
  return !t.ExcludedFromAllInConfigs.empty();
}
