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

#include <algorithm>
#include <string>

#include <cm/memory>

#include "cmFindCommon.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmWindowsRegistry.h"

class cmExecutionStatus;

#if defined(__APPLE__)
#  include <CoreFoundation/CFBundle.h>
#  include <CoreFoundation/CFString.h>
#  include <CoreFoundation/CFURL.h>
#endif

struct cmFindProgramHelper
{
  cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base,
                      cmFindCommonDebugState* debugState)
    : DebugState(debugState)
    , Makefile(makefile)
    , FindBase(base)
    , PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
  {
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
    // Consider platform-specific extensions.
    this->Extensions.push_back(".com");
    this->Extensions.push_back(".exe");
#endif
    // Consider original name with no extensions.
    this->Extensions.emplace_back();
  }

  // List of valid extensions.
  std::vector<std::string> Extensions;

  // Keep track of the best program file found so far.
  std::string BestPath;

  // Current names under consideration.
  std::vector<std::string> Names;

  // Debug state
  cmFindCommonDebugState* DebugState;
  cmMakefile* Makefile;
  cmFindBase const* FindBase;

  cmPolicies::PolicyStatus PolicyCMP0109;

  void AddName(std::string const& name) { this->Names.push_back(name); }
  void SetName(std::string const& name)
  {
    this->Names.clear();
    this->AddName(name);
  }
  bool CheckCompoundNames()
  {
    return std::any_of(this->Names.begin(), this->Names.end(),
                       [this](std::string const& n) -> bool {
                         // Only perform search relative to current directory
                         // if the file name contains a directory separator.
                         return n.find('/') != std::string::npos &&
                           this->CheckDirectoryForName("", n);
                       });
  }
  bool CheckDirectory(std::string const& path)
  {
    return std::any_of(this->Names.begin(), this->Names.end(),
                       [this, &path](std::string const& n) -> bool {
                         return this->CheckDirectoryForName(path, n);
                       });
  }
  bool CheckDirectoryForName(std::string const& path, std::string const& name)
  {
    return std::any_of(this->Extensions.begin(), this->Extensions.end(),
                       [this, &path, &name](std::string const& ext) -> bool {
                         if (!ext.empty() && cmHasSuffix(name, ext)) {
                           return false;
                         }
                         std::string testNameExt = cmStrCat(name, ext);
                         std::string testPath =
                           cmSystemTools::CollapseFullPath(testNameExt, path);
                         if (this->FileIsExecutable(testPath)) {
                           testPath =
                             cmSystemTools::ToNormalizedPathOnDisk(testPath);
                           if (this->FindBase->Validate(testPath)) {
                             this->BestPath = testPath;
                             if (this->DebugState) {
                               this->DebugState->FoundAt(testPath);
                             }
                             return true;
                           }
                         }
                         if (this->DebugState) {
                           this->DebugState->FailedAt(testPath);
                         }
                         return false;
                       });
  }
  bool FileIsExecutable(std::string const& file) const
  {
    if (!this->FileIsExecutableCMP0109(file)) {
      return false;
    }
#ifdef _WIN32
    // Pretend the Windows "python" app installer alias does not exist.
    if (cmSystemTools::LowerCase(file).find("/windowsapps/python") !=
        std::string::npos) {
      std::string dest;
      if (cmSystemTools::ReadSymlink(file, dest) &&
          cmHasLiteralSuffix(dest, "\\AppInstallerPythonRedirector.exe")) {
        return false;
      }
    }
#endif
    return true;
  }
  bool FileIsExecutableCMP0109(std::string const& file) const
  {
    switch (this->PolicyCMP0109) {
      case cmPolicies::OLD:
        return cmSystemTools::FileExists(file, true);
      case cmPolicies::NEW:
        return cmSystemTools::FileIsExecutable(file);
      default:
        break;
    }
    bool const isExeOld = cmSystemTools::FileExists(file, true);
    bool const isExeNew = cmSystemTools::FileIsExecutable(file);
    if (isExeNew == isExeOld) {
      return isExeNew;
    }
    if (isExeNew) {
      this->Makefile->IssueMessage(
        MessageType::AUTHOR_WARNING,
        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
                 "\n"
                 "The file\n"
                 "  ",
                 file,
                 "\n"
                 "is executable but not readable.  "
                 "CMake is ignoring it for compatibility."));
    } else {
      this->Makefile->IssueMessage(
        MessageType::AUTHOR_WARNING,
        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0109),
                 "\n"
                 "The file\n"
                 "  ",
                 file,
                 "\n"
                 "is readable but not executable.  "
                 "CMake is using it for compatibility."));
    }
    return isExeOld;
  }
};

cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
  : cmFindBase("find_program", status)
{
  this->NamesPerDirAllowed = true;
  this->VariableDocumentation = "Path to a program.";
  this->VariableType = cmStateEnums::FILEPATH;
  // Windows Registry views
  // When policy CMP0134 is not NEW, rely on previous behavior:
  if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0134) !=
      cmPolicies::NEW) {
    if (this->Makefile->GetDefinition("CMAKE_SIZEOF_VOID_P") == "8") {
      this->RegistryView = cmWindowsRegistry::View::Reg64_32;
    } else {
      this->RegistryView = cmWindowsRegistry::View::Reg32_64;
    }
  } else {
    this->RegistryView = cmWindowsRegistry::View::Both;
  }
}

// cmFindProgramCommand
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{

  this->CMakePathName = "PROGRAM";

  // call cmFindBase::ParseArguments
  if (!this->ParseArguments(argsIn)) {
    return false;
  }
  if (this->ComputeIfDebugModeWanted(this->VariableName)) {
    this->DebugState = cm::make_unique<cmFindBaseDebugState>(this);
  }

  if (this->IsFound()) {
    this->NormalizeFindResult();
    return true;
  }

  std::string const result = this->FindProgram();
  this->StoreFindResult(result);
  return true;
}

std::string cmFindProgramCommand::FindProgram()
{
  std::string program;

  if (this->SearchAppBundleFirst || this->SearchAppBundleOnly) {
    program = this->FindAppBundle();
  }
  if (program.empty() && !this->SearchAppBundleOnly) {
    program = this->FindNormalProgram();
  }

  if (program.empty() && this->SearchAppBundleLast) {
    program = this->FindAppBundle();
  }
  return program;
}

std::string cmFindProgramCommand::FindNormalProgram()
{
  if (this->NamesPerDir) {
    return this->FindNormalProgramNamesPerDir();
  }
  return this->FindNormalProgramDirsPerName();
}

std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
{
  // Search for all names in each directory.
  cmFindProgramHelper helper(this->Makefile, this, this->DebugState.get());
  for (std::string const& n : this->Names) {
    helper.AddName(n);
  }

  // Check for the names themselves if they contain a directory separator.
  if (helper.CheckCompoundNames()) {
    return helper.BestPath;
  }

  // Search every directory.
  for (std::string const& sp : this->SearchPaths) {
    if (helper.CheckDirectory(sp)) {
      return helper.BestPath;
    }
  }
  // Couldn't find the program.
  return "";
}

std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
{
  // Search the entire path for each name.
  cmFindProgramHelper helper(this->Makefile, this, this->DebugState.get());
  for (std::string const& n : this->Names) {
    // Switch to searching for this name.
    helper.SetName(n);

    // Check for the names themselves if they contain a directory separator.
    if (helper.CheckCompoundNames()) {
      return helper.BestPath;
    }

    // Search every directory.
    for (std::string const& sp : this->SearchPaths) {
      if (helper.CheckDirectory(sp)) {
        return helper.BestPath;
      }
    }
  }
  // Couldn't find the program.
  return "";
}

std::string cmFindProgramCommand::FindAppBundle()
{
  for (std::string const& name : this->Names) {

    std::string appName = name + std::string(".app");
    std::string appPath =
      cmSystemTools::FindDirectory(appName, this->SearchPaths, true);

    if (!appPath.empty()) {
      std::string executable = this->GetBundleExecutable(appPath);
      if (!executable.empty()) {
        return cmSystemTools::CollapseFullPath(executable);
      }
    }
  }

  // Couldn't find app bundle
  return "";
}

std::string cmFindProgramCommand::GetBundleExecutable(
  std::string const& bundlePath)
{
  std::string executable;
  (void)bundlePath;
#if defined(__APPLE__)
  // Started with an example on developer.apple.com about finding bundles
  // and modified from that.

  // Get a CFString of the app bundle path
  // XXX - Is it safe to assume everything is in UTF8?
  CFStringRef bundlePathCFS = CFStringCreateWithCString(
    kCFAllocatorDefault, bundlePath.c_str(), kCFStringEncodingUTF8);

  // Make a CFURLRef from the CFString representation of the
  // bundle’s path.
  CFURLRef bundleURL = CFURLCreateWithFileSystemPath(
    kCFAllocatorDefault, bundlePathCFS, kCFURLPOSIXPathStyle, true);

  // Make a bundle instance using the URLRef.
  CFBundleRef appBundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);

  // returned executableURL is relative to <appbundle>/Contents/MacOS/
  CFURLRef executableURL = CFBundleCopyExecutableURL(appBundle);

  if (executableURL) {
    int const MAX_OSX_PATH_SIZE = 1024;
    UInt8 buffer[MAX_OSX_PATH_SIZE];

    if (CFURLGetFileSystemRepresentation(executableURL, false, buffer,
                                         MAX_OSX_PATH_SIZE)) {
      executable = bundlePath + "/Contents/MacOS/" +
        std::string(reinterpret_cast<char*>(buffer));
    }
    // Only release CFURLRef if it's not null
    CFRelease(executableURL);
  }

  // Any CF objects returned from functions with "create" or
  // "copy" in their names must be released by us!
  CFRelease(bundlePathCFS);
  CFRelease(bundleURL);
  CFRelease(appBundle);
#endif

  return executable;
}

bool cmFindProgram(std::vector<std::string> const& args,
                   cmExecutionStatus& status)
{
  return cmFindProgramCommand(status).InitialPass(args);
}
