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

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
#include "cmake.h"

namespace {

enum IncludeGuardScope
{
  VARIABLE,
  DIRECTORY,
  GLOBAL
};

std::string GetIncludeGuardVariableName(std::string const& filePath)
{
  std::string result = "__INCGUARD_";
#ifndef CMAKE_BOOTSTRAP
  result += cmSystemTools::ComputeStringMD5(filePath);
#else
  result += cmSystemTools::MakeCidentifier(filePath);
#endif
  result += "__";
  return result;
}

bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar)
{
  if (mf->GetProperty(includeGuardVar)) {
    return true;
  }
  cmStateSnapshot dirSnapshot =
    mf->GetStateSnapshot().GetBuildsystemDirectoryParent();
  while (dirSnapshot.GetState()) {
    cmStateDirectory stateDir = dirSnapshot.GetDirectory();
    if (stateDir.GetProperty(includeGuardVar)) {
      return true;
    }
    dirSnapshot = dirSnapshot.GetBuildsystemDirectoryParent();
  }
  return false;
}

} // anonymous namespace

// cmIncludeGuardCommand
bool cmIncludeGuardCommand(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  if (args.size() > 1) {
    status.SetError(
      "given an invalid number of arguments. The command takes at "
      "most 1 argument.");
    return false;
  }

  IncludeGuardScope scope = VARIABLE;

  if (!args.empty()) {
    std::string const& arg = args[0];
    if (arg == "DIRECTORY") {
      scope = DIRECTORY;
    } else if (arg == "GLOBAL") {
      scope = GLOBAL;
    } else {
      status.SetError("given an invalid scope: " + arg);
      return false;
    }
  }

  std::string includeGuardVar = GetIncludeGuardVariableName(
    *status.GetMakefile().GetDefinition("CMAKE_CURRENT_LIST_FILE"));

  cmMakefile* const mf = &status.GetMakefile();

  switch (scope) {
    case VARIABLE:
      if (mf->IsDefinitionSet(includeGuardVar)) {
        status.SetReturnInvoked();
        return true;
      }
      mf->AddDefinitionBool(includeGuardVar, true);
      break;
    case DIRECTORY:
      if (CheckIncludeGuardIsSet(mf, includeGuardVar)) {
        status.SetReturnInvoked();
        return true;
      }
      mf->SetProperty(includeGuardVar, "TRUE");
      break;
    case GLOBAL:
      cmake* const cm = mf->GetCMakeInstance();
      if (cm->GetProperty(includeGuardVar)) {
        status.SetReturnInvoked();
        return true;
      }
      cm->SetProperty(includeGuardVar, "TRUE");
      break;
  }

  return true;
}
