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

#include "cmFileInstaller.h"

#include <map>
#include <sstream>
#include <utility>

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

#include "cm_sys_stat.h"

#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

using namespace cmFSPermissions;

cmFileInstaller::cmFileInstaller(cmExecutionStatus& status)
  : cmFileCopier(status, "INSTALL")
{
  // Installation does not use source permissions by default.
  this->UseSourcePermissions = false;
  // Check whether to copy files always or only if they have changed.
  std::string install_always;
  if (cmSystemTools::GetEnv("CMAKE_INSTALL_ALWAYS", install_always)) {
    this->Always = cmIsOn(install_always);
  }
  // Get the current manifest.
  this->Manifest =
    this->Makefile->GetSafeDefinition("CMAKE_INSTALL_MANIFEST_FILES");
}
cmFileInstaller::~cmFileInstaller()
{
  // Save the updated install manifest.
  this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
                                this->Manifest);
}

void cmFileInstaller::ManifestAppend(std::string const& file)
{
  if (!this->Manifest.empty()) {
    this->Manifest += ";";
  }
  this->Manifest += file.substr(this->DestDirLength);
}

std::string const& cmFileInstaller::ToName(std::string const& fromName)
{
  return this->Rename.empty() ? fromName : this->Rename;
}

void cmFileInstaller::ReportCopy(std::string const& toFile, Type type,
                                 bool copy)
{
  if (!this->MessageNever && (copy || !this->MessageLazy)) {
    std::string message =
      cmStrCat((copy ? "Installing: " : "Up-to-date: "), toFile);
    this->Makefile->DisplayStatus(message, -1);
  }
  if (type != TypeDir) {
    // Add the file to the manifest.
    this->ManifestAppend(toFile);
  }
}
bool cmFileInstaller::ReportMissing(std::string const& fromFile)
{
  return (this->Optional || this->cmFileCopier::ReportMissing(fromFile));
}
bool cmFileInstaller::Install(std::string const& fromFile,
                              std::string const& toFile)
{
  // Support installing from empty source to make a directory.
  if (this->InstallType == cmInstallType_DIRECTORY && fromFile.empty()) {
    return this->InstallDirectory(fromFile, toFile, MatchProperties());
  }
  return this->cmFileCopier::Install(fromFile, toFile);
}

bool cmFileInstaller::InstallFile(std::string const& fromFile,
                                  std::string const& toFile,
                                  MatchProperties match_properties)
{
  if (this->InstallMode == cmInstallMode::COPY) {
    return this->cmFileCopier::InstallFile(fromFile, toFile, match_properties);
  }

  std::string newFromFile;

  if (this->InstallMode == cmInstallMode::REL_SYMLINK ||
      this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY ||
      this->InstallMode == cmInstallMode::SYMLINK ||
      this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
    // Try to get a relative path.
    std::string toDir = cmSystemTools::GetParentDirectory(toFile);
    newFromFile = cmSystemTools::ForceToRelativePath(toDir, fromFile);

    // Double check that we can restore the original path.
    std::string reassembled =
      cmSystemTools::CollapseFullPath(newFromFile, toDir);
    if (!cmSystemTools::ComparePath(reassembled, fromFile)) {
      if (this->InstallMode == cmInstallMode::SYMLINK ||
          this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
        // User does not mind, silently proceed with absolute path.
        newFromFile = fromFile;
      } else if (this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY) {
        // User expects a relative symbolic link or a copy.
        // Since an absolute symlink won't do, copy instead.
        return this->cmFileCopier::InstallFile(fromFile, toFile,
                                               match_properties);
      } else {
        // We cannot meet user's expectation (REL_SYMLINK)
        auto e = cmStrCat(this->Name,
                          " cannot determine relative path for symlink to \"",
                          newFromFile, "\" at \"", toFile, "\".");
        this->Status.SetError(e);
        return false;
      }
    }
  } else {
    newFromFile = fromFile; // stick with absolute path
  }

  // Compare the symlink value to that at the destination if not
  // always installing.
  bool copy = true;
  if (!this->Always) {
    std::string oldSymlinkTarget;
    if (cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget)) {
      if (newFromFile == oldSymlinkTarget) {
        copy = false;
      }
    }
  }

  // Inform the user about this file installation.
  this->ReportCopy(toFile, TypeLink, copy);

  if (copy) {
    // Remove the destination file so we can always create the symlink.
    cmSystemTools::RemoveFile(toFile);

    // Create destination directory if it doesn't exist
    cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(toFile));

    // Create the symlink.
    if (!cmSystemTools::CreateSymlink(newFromFile, toFile)) {
      if (this->InstallMode == cmInstallMode::ABS_SYMLINK_OR_COPY ||
          this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY ||
          this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
        // Failed to create a symbolic link, fall back to copying.
        return this->cmFileCopier::InstallFile(newFromFile, toFile,
                                               match_properties);
      }

      auto e = cmStrCat(this->Name, " cannot create symlink to \"",
                        newFromFile, "\" at \"", toFile,
                        "\": ", cmSystemTools::GetLastSystemError(), "\".");
      this->Status.SetError(e);
      return false;
    }
  }

  return true;
}

void cmFileInstaller::DefaultFilePermissions()
{
  this->cmFileCopier::DefaultFilePermissions();
  // Add execute permissions based on the target type.
  switch (this->InstallType) {
    case cmInstallType_SHARED_LIBRARY:
    case cmInstallType_MODULE_LIBRARY:
      if (this->Makefile->IsOn("CMAKE_INSTALL_SO_NO_EXE")) {
        break;
      }
      CM_FALLTHROUGH;
    case cmInstallType_EXECUTABLE:
    case cmInstallType_PROGRAMS:
      this->FilePermissions |= mode_owner_execute;
      this->FilePermissions |= mode_group_execute;
      this->FilePermissions |= mode_world_execute;
      break;
    default:
      break;
  }
}

bool cmFileInstaller::Parse(std::vector<std::string> const& args)
{
  if (!this->cmFileCopier::Parse(args)) {
    return false;
  }

  if (!this->Rename.empty()) {
    if (!this->FilesFromDir.empty()) {
      this->Status.SetError("INSTALL option RENAME may not be "
                            "combined with FILES_FROM_DIR.");
      return false;
    }
    if (this->InstallType != cmInstallType_FILES &&
        this->InstallType != cmInstallType_PROGRAMS) {
      this->Status.SetError("INSTALL option RENAME may be used "
                            "only with FILES or PROGRAMS.");
      return false;
    }
    if (this->Files.size() > 1) {
      this->Status.SetError("INSTALL option RENAME may be used "
                            "only with one file.");
      return false;
    }
  }

  if (!this->HandleInstallDestination()) {
    return false;
  }

  if (((this->MessageAlways ? 1 : 0) + (this->MessageLazy ? 1 : 0) +
       (this->MessageNever ? 1 : 0)) > 1) {
    this->Status.SetError("INSTALL options MESSAGE_ALWAYS, "
                          "MESSAGE_LAZY, and MESSAGE_NEVER "
                          "are mutually exclusive.");
    return false;
  }

  static std::map<cm::string_view, cmInstallMode> const install_mode_dict{
    { "ABS_SYMLINK"_s, cmInstallMode::ABS_SYMLINK },
    { "ABS_SYMLINK_OR_COPY"_s, cmInstallMode::ABS_SYMLINK_OR_COPY },
    { "REL_SYMLINK"_s, cmInstallMode::REL_SYMLINK },
    { "REL_SYMLINK_OR_COPY"_s, cmInstallMode::REL_SYMLINK_OR_COPY },
    { "SYMLINK"_s, cmInstallMode::SYMLINK },
    { "SYMLINK_OR_COPY"_s, cmInstallMode::SYMLINK_OR_COPY }
  };

  std::string install_mode;
  cmSystemTools::GetEnv("CMAKE_INSTALL_MODE", install_mode);
  if (install_mode.empty() || install_mode == "COPY"_s) {
    this->InstallMode = cmInstallMode::COPY;
  } else {
    auto it = install_mode_dict.find(install_mode);
    if (it != install_mode_dict.end()) {
      this->InstallMode = it->second;
    } else {
      auto e = cmStrCat("Unrecognized value '", install_mode,
                        "' for environment variable CMAKE_INSTALL_MODE");
      this->Status.SetError(e);
      return false;
    }
  }

  return true;
}

bool cmFileInstaller::CheckKeyword(std::string const& arg)
{
  if (arg == "TYPE") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingType;
    }
  } else if (arg == "FILES") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingFiles;
    }
  } else if (arg == "RENAME") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingRename;
    }
  } else if (arg == "OPTIONAL") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingNone;
      this->Optional = true;
    }
  } else if (arg == "MESSAGE_ALWAYS") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingNone;
      this->MessageAlways = true;
    }
  } else if (arg == "MESSAGE_LAZY") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingNone;
      this->MessageLazy = true;
    }
  } else if (arg == "MESSAGE_NEVER") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      this->Doing = DoingNone;
      this->MessageNever = true;
    }
  } else if (arg == "PERMISSIONS") {
    if (this->CurrentMatchRule) {
      this->Doing = DoingPermissionsMatch;
    } else {
      // file(INSTALL) aliases PERMISSIONS to FILE_PERMISSIONS
      this->Doing = DoingPermissionsFile;
      this->UseGivenPermissionsFile = true;
    }
  } else if (arg == "DIR_PERMISSIONS") {
    if (this->CurrentMatchRule) {
      this->NotAfterMatch(arg);
    } else {
      // file(INSTALL) aliases DIR_PERMISSIONS to DIRECTORY_PERMISSIONS
      this->Doing = DoingPermissionsDir;
      this->UseGivenPermissionsDir = true;
    }
  } else if (arg == "COMPONENTS" || arg == "CONFIGURATIONS" ||
             arg == "PROPERTIES") {
    std::ostringstream e;
    e << "INSTALL called with old-style " << arg << " argument.  "
      << "This script was generated with an older version of CMake.  "
      << "Re-run this cmake version on your build tree.";
    this->Status.SetError(e.str());
    this->Doing = DoingError;
  } else {
    return this->cmFileCopier::CheckKeyword(arg);
  }
  return true;
}

bool cmFileInstaller::CheckValue(std::string const& arg)
{
  switch (this->Doing) {
    case DoingType:
      if (!this->GetTargetTypeFromString(arg)) {
        this->Doing = DoingError;
      }
      break;
    case DoingRename:
      this->Rename = arg;
      break;
    default:
      return this->cmFileCopier::CheckValue(arg);
  }
  return true;
}

bool cmFileInstaller::GetTargetTypeFromString(std::string const& stype)
{
  if (stype == "EXECUTABLE") {
    this->InstallType = cmInstallType_EXECUTABLE;
  } else if (stype == "FILE") {
    this->InstallType = cmInstallType_FILES;
  } else if (stype == "PROGRAM") {
    this->InstallType = cmInstallType_PROGRAMS;
  } else if (stype == "STATIC_LIBRARY") {
    this->InstallType = cmInstallType_STATIC_LIBRARY;
  } else if (stype == "SHARED_LIBRARY") {
    this->InstallType = cmInstallType_SHARED_LIBRARY;
  } else if (stype == "MODULE") {
    this->InstallType = cmInstallType_MODULE_LIBRARY;
  } else if (stype == "DIRECTORY") {
    this->InstallType = cmInstallType_DIRECTORY;
  } else {
    std::ostringstream e;
    e << "Option TYPE given unknown value \"" << stype << "\".";
    this->Status.SetError(e.str());
    return false;
  }
  return true;
}

bool cmFileInstaller::HandleInstallDestination()
{
  std::string& destination = this->Destination;

  // allow for / to be a valid destination
  if (destination.size() < 2 && destination != "/") {
    this->Status.SetError("called with inappropriate arguments. "
                          "No DESTINATION provided or .");
    return false;
  }

  std::string sdestdir;
  if (cmSystemTools::GetEnv("DESTDIR", sdestdir) && !sdestdir.empty()) {
    cmSystemTools::ConvertToUnixSlashes(sdestdir);
    char ch1 = destination[0];
    char ch2 = destination[1];
    char ch3 = 0;
    if (destination.size() > 2) {
      ch3 = destination[2];
    }
    int skip = 0;
    if (ch1 != '/') {
      int relative = 0;
      if (((ch1 >= 'a' && ch1 <= 'z') || (ch1 >= 'A' && ch1 <= 'Z')) &&
          ch2 == ':') {
        // Assume windows
        // let's do some destdir magic:
        skip = 2;
        if (ch3 != '/') {
          relative = 1;
        }
      } else {
        relative = 1;
      }
      if (relative) {
        // This is relative path on unix or windows. Since we are doing
        // destdir, this case does not make sense.
        this->Status.SetError(
          "called with relative DESTINATION. This "
          "does not make sense when using DESTDIR. Specify "
          "absolute path or remove DESTDIR environment variable.");
        return false;
      }
    } else {
      if (ch2 == '/') {
        // looks like a network path.
        std::string message =
          cmStrCat("called with network path DESTINATION. This "
                   "does not make sense when using DESTDIR. Specify local "
                   "absolute path or remove DESTDIR environment variable."
                   "\nDESTINATION=\n",
                   destination);
        this->Status.SetError(message);
        return false;
      }
    }
    destination = sdestdir + destination.substr(skip);
    this->DestDirLength = static_cast<int>(sdestdir.size());
  }

  // check if default dir creation permissions were set
  mode_t default_dir_mode_v = 0;
  mode_t* default_dir_mode = &default_dir_mode_v;
  if (!this->GetDefaultDirectoryPermissions(&default_dir_mode)) {
    return false;
  }

  if (this->InstallType != cmInstallType_DIRECTORY) {
    if (!cmSystemTools::FileExists(destination)) {
      if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) {
        std::string errstring = "cannot create directory: " + destination +
          ". Maybe need administrative privileges.";
        this->Status.SetError(errstring);
        return false;
      }
    }
    if (!cmSystemTools::FileIsDirectory(destination)) {
      std::string errstring =
        "INSTALL destination: " + destination + " is not a directory.";
      this->Status.SetError(errstring);
      return false;
    }
  }
  return true;
}
