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

#include <cstddef>
#include <functional>

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

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmPropertyDefinition.h"
#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTest.h"
#include "cmValue.h"
#include "cmake.h"

namespace {
enum OutType
{
  OutValue,
  OutDefined,
  OutBriefDoc,
  OutFullDoc,
  OutSet
};

// Implementation of each property type.
bool HandleGlobalMode(cmExecutionStatus& status, std::string const& name,
                      OutType infoType, std::string const& variable,
                      std::string const& propertyName);
bool HandleDirectoryMode(cmExecutionStatus& status, std::string const& name,
                         OutType infoType, std::string const& variable,
                         std::string const& propertyName);
bool HandleTargetMode(cmExecutionStatus& status, std::string const& name,
                      OutType infoType, std::string const& variable,
                      std::string const& propertyName);
bool HandleSourceMode(cmExecutionStatus& status, std::string const& name,
                      OutType infoType, std::string const& variable,
                      std::string const& propertyName,
                      cmMakefile& directory_makefile,
                      bool source_file_paths_should_be_absolute);
bool HandleTestMode(cmExecutionStatus& status, std::string const& name,
                    OutType infoType, std::string const& variable,
                    std::string const& propertyName,
                    cmMakefile& directory_makefile);
bool HandleVariableMode(cmExecutionStatus& status, std::string const& name,
                        OutType infoType, std::string const& variable,
                        std::string const& propertyName);
bool HandleCacheMode(cmExecutionStatus& status, std::string const& name,
                     OutType infoType, std::string const& variable,
                     std::string const& propertyName);
bool HandleInstallMode(cmExecutionStatus& status, std::string const& name,
                       OutType infoType, std::string const& variable,
                       std::string const& propertyName);
}

bool cmGetPropertyCommand(std::vector<std::string> const& args,
                          cmExecutionStatus& status)
{
  OutType infoType = OutValue;
  if (args.size() < 3) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  // The cmake variable in which to store the result.
  std::string const& variable = args[0];

  std::string name;
  std::string propertyName;

  std::vector<std::string> source_file_directories;
  std::vector<std::string> source_file_target_directories;
  bool source_file_directory_option_enabled = false;
  bool source_file_target_option_enabled = false;

  std::string test_directory;
  bool test_directory_option_enabled = false;

  // Get the scope from which to get the property.
  cmProperty::ScopeType scope;
  if (args[1] == "GLOBAL") {
    scope = cmProperty::GLOBAL;
  } else if (args[1] == "DIRECTORY") {
    scope = cmProperty::DIRECTORY;
  } else if (args[1] == "TARGET") {
    scope = cmProperty::TARGET;
  } else if (args[1] == "SOURCE") {
    scope = cmProperty::SOURCE_FILE;
  } else if (args[1] == "TEST") {
    scope = cmProperty::TEST;
  } else if (args[1] == "VARIABLE") {
    scope = cmProperty::VARIABLE;
  } else if (args[1] == "CACHE") {
    scope = cmProperty::CACHE;
  } else if (args[1] == "INSTALL") {
    scope = cmProperty::INSTALL;
  } else {
    status.SetError(cmStrCat(
      "given invalid scope ", args[1],
      ".  "
      "Valid scopes are "
      "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE, INSTALL."));
    return false;
  }

  // Parse remaining arguments.
  enum Doing
  {
    DoingNone,
    DoingName,
    DoingProperty,
    DoingType,
    DoingSourceDirectory,
    DoingSourceTargetDirectory,
    DoingTestDirectory,
  };
  Doing doing = DoingName;
  for (unsigned int i = 2; i < args.size(); ++i) {
    if (args[i] == "PROPERTY") {
      doing = DoingProperty;
    } else if (args[i] == "BRIEF_DOCS") {
      doing = DoingNone;
      infoType = OutBriefDoc;
    } else if (args[i] == "FULL_DOCS") {
      doing = DoingNone;
      infoType = OutFullDoc;
    } else if (args[i] == "SET") {
      doing = DoingNone;
      infoType = OutSet;
    } else if (args[i] == "DEFINED") {
      doing = DoingNone;
      infoType = OutDefined;
    } else if (doing == DoingName) {
      doing = DoingNone;
      name = args[i];
    } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
               args[i] == "DIRECTORY") {
      doing = DoingSourceDirectory;
      source_file_directory_option_enabled = true;
    } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
               args[i] == "TARGET_DIRECTORY") {
      doing = DoingSourceTargetDirectory;
      source_file_target_option_enabled = true;
    } else if (doing == DoingNone && scope == cmProperty::TEST &&
               args[i] == "DIRECTORY") {
      doing = DoingTestDirectory;
      test_directory_option_enabled = true;
    } else if (doing == DoingSourceDirectory) {
      source_file_directories.push_back(args[i]);
      doing = DoingNone;
    } else if (doing == DoingSourceTargetDirectory) {
      source_file_target_directories.push_back(args[i]);
      doing = DoingNone;
    } else if (doing == DoingTestDirectory) {
      test_directory = args[i];
      doing = DoingNone;
    } else if (doing == DoingProperty) {
      doing = DoingNone;
      propertyName = args[i];
    } else {
      status.SetError(cmStrCat("given invalid argument \"", args[i], "\"."));
      return false;
    }
  }

  // Make sure a property name was found.
  if (propertyName.empty()) {
    status.SetError("not given a PROPERTY <name> argument.");
    return false;
  }

  std::vector<cmMakefile*> source_file_directory_makefiles;
  bool source_file_scopes_handled =
    SetPropertyCommand::HandleAndValidateSourceFileDirectoryScopes(
      status, source_file_directory_option_enabled,
      source_file_target_option_enabled, source_file_directories,
      source_file_target_directories, source_file_directory_makefiles);
  cmMakefile* test_directory_makefile;
  bool test_scopes_handled =
    SetPropertyCommand::HandleAndValidateTestDirectoryScopes(
      status, test_directory_option_enabled, test_directory,
      test_directory_makefile);
  if (!(source_file_scopes_handled && test_scopes_handled)) {
    return false;
  }

  // Compute requested output.
  if (infoType == OutBriefDoc) {
    // Lookup brief documentation.
    std::string output;
    if (cmPropertyDefinition const* def =
          status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
                                                                 scope)) {
      output = def->GetShortDescription();
    }
    if (output.empty()) {
      output = "NOTFOUND";
    }
    status.GetMakefile().AddDefinition(variable, output);
  } else if (infoType == OutFullDoc) {
    // Lookup full documentation.
    std::string output;
    if (cmPropertyDefinition const* def =
          status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
                                                                 scope)) {
      output = def->GetFullDescription();
    }
    if (output.empty()) {
      output = "NOTFOUND";
    }
    status.GetMakefile().AddDefinition(variable, output);
  } else if (infoType == OutDefined) {
    // Lookup if the property is defined
    if (status.GetMakefile().GetState()->GetPropertyDefinition(propertyName,
                                                               scope)) {
      status.GetMakefile().AddDefinition(variable, "1");
    } else {
      status.GetMakefile().AddDefinition(variable, "0");
    }
  } else {
    // Dispatch property getting.
    cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]);
    bool source_file_paths_should_be_absolute =
      source_file_directory_option_enabled ||
      source_file_target_option_enabled;

    switch (scope) {
      case cmProperty::GLOBAL:
        return HandleGlobalMode(status, name, infoType, variable,
                                propertyName);
      case cmProperty::DIRECTORY:
        return HandleDirectoryMode(status, name, infoType, variable,
                                   propertyName);
      case cmProperty::TARGET:
        return HandleTargetMode(status, name, infoType, variable,
                                propertyName);
      case cmProperty::SOURCE_FILE:
        return HandleSourceMode(status, name, infoType, variable, propertyName,
                                directory_scope_mf,
                                source_file_paths_should_be_absolute);
      case cmProperty::TEST:
        return HandleTestMode(status, name, infoType, variable, propertyName,
                              *test_directory_makefile);
      case cmProperty::VARIABLE:
        return HandleVariableMode(status, name, infoType, variable,
                                  propertyName);
      case cmProperty::CACHE:
        return HandleCacheMode(status, name, infoType, variable, propertyName);
      case cmProperty::INSTALL:
        return HandleInstallMode(status, name, infoType, variable,
                                 propertyName);

      case cmProperty::CACHED_VARIABLE:
        break; // should never happen
    }
  }

  return true;
}

namespace GetPropertyCommand {
bool GetSourceFilePropertyGENERATED(
  std::string const& name, cmMakefile& mf,
  std::function<bool(bool)> const& storeResult)
{
  // Globally set as generated?
  // Note: If the given "name" only contains a filename or a relative path
  //       the file's location is ambiguous. In general, one would expect
  //       it in the source-directory, because that is where source files
  //       are located normally. However, generated files are normally
  //       generated in the build-directory. Therefore, we first check for
  //       a generated file in the build-directory before we check for a
  //       generated file in the source-directory.
  {
    auto file =
      cmSystemTools::CollapseFullPath(name, mf.GetCurrentBinaryDirectory());
    if (mf.GetGlobalGenerator()->IsGeneratedFile(file)) {
      return storeResult(true);
    }
  }
  {
    auto file =
      cmSystemTools::CollapseFullPath(name, mf.GetCurrentSourceDirectory());
    if (mf.GetGlobalGenerator()->IsGeneratedFile(file)) {
      return storeResult(true);
    }
  }
  // Skip checking the traditional/local property.
  return storeResult(false);
}
}

namespace {

// Implementation of result storage.
template <typename ValueType>
bool StoreResult(OutType infoType, cmMakefile& makefile,
                 std::string const& variable, ValueType value)
{
  if (infoType == OutSet) {
    makefile.AddDefinition(variable, value ? "1" : "0");
  } else // if(infoType == OutValue)
  {
    if (value) {
      makefile.AddDefinition(variable, value);
    } else {
      makefile.RemoveDefinition(variable);
    }
  }
  return true;
}
template <>
bool StoreResult(OutType infoType, cmMakefile& makefile,
                 std::string const& variable, std::nullptr_t value)
{
  return StoreResult(infoType, makefile, variable, cmValue(value));
}

bool HandleGlobalMode(cmExecutionStatus& status, std::string const& name,
                      OutType infoType, std::string const& variable,
                      std::string const& propertyName)
{
  if (!name.empty()) {
    status.SetError("given name for GLOBAL scope.");
    return false;
  }

  // Get the property.
  cmake* cm = status.GetMakefile().GetCMakeInstance();
  return StoreResult(infoType, status.GetMakefile(), variable,
                     cm->GetState()->GetGlobalProperty(propertyName));
}

bool HandleDirectoryMode(cmExecutionStatus& status, std::string const& name,
                         OutType infoType, std::string const& variable,
                         std::string const& propertyName)
{
  // Default to the current directory.
  cmMakefile* mf = &status.GetMakefile();

  // Lookup the directory if given.
  if (!name.empty()) {
    // Construct the directory name.  Interpret relative paths with
    // respect to the current directory.
    std::string dir = cmSystemTools::CollapseFullPath(
      name, status.GetMakefile().GetCurrentSourceDirectory());

    // Lookup the generator.
    mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
    if (!mf) {
      // Could not find the directory.
      status.SetError(
        "DIRECTORY scope provided but requested directory was not found. "
        "This could be because the directory argument was invalid or, "
        "it is valid but has not been processed yet.");
      return false;
    }
  }

  // Get the property.
  return StoreResult(infoType, status.GetMakefile(), variable,
                     mf->GetProperty(propertyName));
}

bool HandleTargetMode(cmExecutionStatus& status, std::string const& name,
                      OutType infoType, std::string const& variable,
                      std::string const& propertyName)
{
  if (name.empty()) {
    status.SetError("not given name for TARGET scope.");
    return false;
  }

  if (cmTarget* target = status.GetMakefile().FindTargetToUse(name)) {
    if (propertyName == "ALIASED_TARGET" || propertyName == "ALIAS_GLOBAL") {
      if (status.GetMakefile().IsAlias(name)) {
        if (propertyName == "ALIASED_TARGET") {

          return StoreResult(infoType, status.GetMakefile(), variable,
                             target->GetName().c_str());
        }
        if (propertyName == "ALIAS_GLOBAL") {
          return StoreResult(
            infoType, status.GetMakefile(), variable,
            status.GetMakefile().GetGlobalGenerator()->IsAlias(name)
              ? "TRUE"
              : "FALSE");
        }
      }
      return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
    }
    cmValue prop =
      target->GetComputedProperty(propertyName, status.GetMakefile());
    if (!prop) {
      prop = target->GetProperty(propertyName);
    }
    return StoreResult(infoType, status.GetMakefile(), variable, prop);
  }
  status.SetError(cmStrCat("could not find TARGET ", name,
                           ".  Perhaps it has not yet been created."));
  return false;
}

bool HandleSourceMode(cmExecutionStatus& status, std::string const& name,
                      OutType infoType, std::string const& variable,
                      std::string const& propertyName,
                      cmMakefile& directory_makefile,
                      bool const source_file_paths_should_be_absolute)
{
  if (name.empty()) {
    status.SetError("not given name for SOURCE scope.");
    return false;
  }

  // Special handling for GENERATED property.
  // Note: Only, if CMP0163 is set to NEW!
  if (propertyName == "GENERATED"_s) {
    auto& mf = status.GetMakefile();
    auto cmp0163 = directory_makefile.GetPolicyStatus(cmPolicies::CMP0163);
    bool const cmp0163new =
      cmp0163 != cmPolicies::OLD && cmp0163 != cmPolicies::WARN;
    if (cmp0163new) {
      return GetPropertyCommand::GetSourceFilePropertyGENERATED(
        name, mf, [infoType, &variable, &mf](bool isGenerated) -> bool {
          // Set the value on the original Makefile scope, not the scope of the
          // requested directory.
          return StoreResult(infoType, mf, variable,
                             (isGenerated) ? cmValue("1") : cmValue("0"));
        });
    }
  }

  // Get the source file.
  std::string const source_file_absolute_path =
    SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
      status, name, source_file_paths_should_be_absolute);
  if (cmSourceFile* sf =
        directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
    // Set the value on the original Makefile scope, not the scope of the
    // requested directory.
    return StoreResult(infoType, status.GetMakefile(), variable,
                       sf->GetPropertyForUser(propertyName));
  }
  status.SetError(
    cmStrCat("given SOURCE name that could not be found or created: ",
             source_file_absolute_path));
  return false;
}

bool HandleTestMode(cmExecutionStatus& status, std::string const& name,
                    OutType infoType, std::string const& variable,
                    std::string const& propertyName, cmMakefile& test_makefile)
{
  if (name.empty()) {
    status.SetError("not given name for TEST scope.");
    return false;
  }

  // Loop over all tests looking for matching names.
  if (cmTest* test = test_makefile.GetTest(name)) {
    return StoreResult(infoType, status.GetMakefile(), variable,
                       test->GetProperty(propertyName));
  }

  // If not found it is an error.
  status.SetError(cmStrCat("given TEST name that does not exist: ", name));
  return false;
}

bool HandleVariableMode(cmExecutionStatus& status, std::string const& name,
                        OutType infoType, std::string const& variable,
                        std::string const& propertyName)
{
  if (!name.empty()) {
    status.SetError("given name for VARIABLE scope.");
    return false;
  }

  return StoreResult(infoType, status.GetMakefile(), variable,
                     status.GetMakefile().GetDefinition(propertyName));
}

bool HandleCacheMode(cmExecutionStatus& status, std::string const& name,
                     OutType infoType, std::string const& variable,
                     std::string const& propertyName)
{
  if (name.empty()) {
    status.SetError("not given name for CACHE scope.");
    return false;
  }

  cmValue value = nullptr;
  if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) {
    value = status.GetMakefile().GetState()->GetCacheEntryProperty(
      name, propertyName);
  }
  StoreResult(infoType, status.GetMakefile(), variable, value);
  return true;
}

bool HandleInstallMode(cmExecutionStatus& status, std::string const& name,
                       OutType infoType, std::string const& variable,
                       std::string const& propertyName)
{
  if (name.empty()) {
    status.SetError("not given name for INSTALL scope.");
    return false;
  }

  // Get the installed file.
  cmake* cm = status.GetMakefile().GetCMakeInstance();

  if (cmInstalledFile* file =
        cm->GetOrCreateInstalledFile(&status.GetMakefile(), name)) {
    std::string value;
    bool isSet = file->GetProperty(propertyName, value);

    return StoreResult(infoType, status.GetMakefile(), variable,
                       isSet ? value.c_str() : nullptr);
  }
  status.SetError(
    cmStrCat("given INSTALL name that could not be found or created: ", name));
  return false;
}
}
