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

#include "cmBase32.h"
#include "cmCryptoHash.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"

#include <vector>

cmFilePathChecksum::cmFilePathChecksum()
{
}

cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir,
                                       std::string const& currentBinDir,
                                       std::string const& projectSrcDir,
                                       std::string const& projectBinDir)
{
  setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir);
}

cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile)
{
  setupParentDirs(makefile->GetCurrentSourceDirectory(),
                  makefile->GetCurrentBinaryDirectory(),
                  makefile->GetHomeDirectory(),
                  makefile->GetHomeOutputDirectory());
}

void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir,
                                         std::string const& currentBinDir,
                                         std::string const& projectSrcDir,
                                         std::string const& projectBinDir)
{
  this->parentDirs[0].first = cmsys::SystemTools::GetRealPath(currentSrcDir);
  this->parentDirs[1].first = cmsys::SystemTools::GetRealPath(currentBinDir);
  this->parentDirs[2].first = cmsys::SystemTools::GetRealPath(projectSrcDir);
  this->parentDirs[3].first = cmsys::SystemTools::GetRealPath(projectBinDir);

  this->parentDirs[0].second = "CurrentSource";
  this->parentDirs[1].second = "CurrentBinary";
  this->parentDirs[2].second = "ProjectSource";
  this->parentDirs[3].second = "ProjectBinary";
}

std::string cmFilePathChecksum::get(std::string const& filePath) const
{
  std::string relPath;
  std::string relSeed;
  {
    std::string const fileReal = cmsys::SystemTools::GetRealPath(filePath);
    std::string parentDir;
    // Find closest project parent directory
    for (auto const& pDir : this->parentDirs) {
      if (!pDir.first.empty() &&
          cmsys::SystemTools::IsSubDirectory(fileReal, pDir.first)) {
        parentDir = pDir.first;
        relSeed = pDir.second;
        break;
      }
    }
    // Use file system root as fallback parent directory
    if (parentDir.empty()) {
      relSeed = "FileSystemRoot";
      cmsys::SystemTools::SplitPathRootComponent(fileReal, &parentDir);
    }
    // Calculate relative path from project parent directory
    relPath = cmsys::SystemTools::RelativePath(
      parentDir, cmsys::SystemTools::GetParentDirectory(fileReal));
  }

  // Calculate the file ( seed + relative path ) binary checksum
  std::vector<unsigned char> hashBytes =
    cmCryptoHash(cmCryptoHash::AlgoSHA256).ByteHashString(relSeed + relPath);

  // Convert binary checksum to string
  return cmBase32Encoder().encodeString(&hashBytes.front(), hashBytes.size(),
                                        false);
}

std::string cmFilePathChecksum::getPart(std::string const& filePath,
                                        size_t length) const
{
  return get(filePath).substr(0, length);
}
