//===--- extra/modularize/ModularizeUtilities.cpp -------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements a class for loading and validating a module map or
// header list by checking that all headers in the corresponding directories
// are accounted for.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "CoverageChecker.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "ModularizeUtilities.h"

using namespace clang;
using namespace llvm;
using namespace Modularize;

namespace {
// Subclass TargetOptions so we can construct it inline with
// the minimal option, the triple.
class ModuleMapTargetOptions : public clang::TargetOptions {
public:
  ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); }
};
} // namespace

// ModularizeUtilities class implementation.

// Constructor.
ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
                                         llvm::StringRef Prefix,
                                         llvm::StringRef ProblemFilesListPath)
    : InputFilePaths(InputPaths), HeaderPrefix(Prefix),
      ProblemFilesPath(ProblemFilesListPath), HasModuleMap(false),
      MissingHeaderCount(0),
      // Init clang stuff needed for loading the module map and preprocessing.
      LangOpts(new LangOptions()), DiagIDs(new DiagnosticIDs()),
      DiagnosticOpts(new DiagnosticOptions()),
      DC(llvm::errs(), DiagnosticOpts.get()),
      Diagnostics(
          new DiagnosticsEngine(DiagIDs, DiagnosticOpts.get(), &DC, false)),
      TargetOpts(new ModuleMapTargetOptions()),
      Target(TargetInfo::CreateTargetInfo(*Diagnostics, TargetOpts)),
      FileMgr(new FileManager(FileSystemOpts)),
      SourceMgr(new SourceManager(*Diagnostics, *FileMgr, false)),
      HeaderInfo(new HeaderSearch(std::make_shared<HeaderSearchOptions>(),
                                  *SourceMgr, *Diagnostics, *LangOpts,
                                  Target.get())) {}

// Create instance of ModularizeUtilities, to simplify setting up
// subordinate objects.
ModularizeUtilities *ModularizeUtilities::createModularizeUtilities(
    std::vector<std::string> &InputPaths, llvm::StringRef Prefix,
    llvm::StringRef ProblemFilesListPath) {

  return new ModularizeUtilities(InputPaths, Prefix, ProblemFilesListPath);
}

// Load all header lists and dependencies.
std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() {
  // For each input file.
  for (auto I = InputFilePaths.begin(), E = InputFilePaths.end(); I != E; ++I) {
    llvm::StringRef InputPath = *I;
    // If it's a module map.
    if (InputPath.endswith(".modulemap")) {
      // Load the module map.
      if (std::error_code EC = loadModuleMap(InputPath))
        return EC;
    }
    else {
      // Else we assume it's a header list and load it.
      if (std::error_code EC = loadSingleHeaderListsAndDependencies(InputPath)) {
        errs() << "modularize: error: Unable to get header list '" << InputPath
          << "': " << EC.message() << '\n';
        return EC;
      }
    }
  }
  // If we have a problem files list.
  if (ProblemFilesPath.size() != 0) {
    // Load problem files list.
    if (std::error_code EC = loadProblemHeaderList(ProblemFilesPath)) {
      errs() << "modularize: error: Unable to get problem header list '" << ProblemFilesPath
        << "': " << EC.message() << '\n';
      return EC;
    }
  }
  return std::error_code();
}

// Do coverage checks.
// For each loaded module map, do header coverage check.
// Starting from the directory of the module.map file,
// Find all header files, optionally looking only at files
// covered by the include path options, and compare against
// the headers referenced by the module.map file.
// Display warnings for unaccounted-for header files.
// Returns 0 if there were no errors or warnings, 1 if there
// were warnings, 2 if any other problem, such as a bad
// module map path argument was specified.
std::error_code ModularizeUtilities::doCoverageCheck(
    std::vector<std::string> &IncludePaths,
    llvm::ArrayRef<std::string> CommandLine) {
  int ModuleMapCount = ModuleMaps.size();
  int ModuleMapIndex;
  std::error_code EC;
  for (ModuleMapIndex = 0; ModuleMapIndex < ModuleMapCount; ++ModuleMapIndex) {
    std::unique_ptr<clang::ModuleMap> &ModMap = ModuleMaps[ModuleMapIndex];
    auto Checker = CoverageChecker::createCoverageChecker(
        InputFilePaths[ModuleMapIndex], IncludePaths, CommandLine,
        ModMap.get());
    std::error_code LocalEC = Checker->doChecks();
    if (LocalEC.value() > 0)
      EC = LocalEC;
  }
  return EC;
}

// Load single header list and dependencies.
std::error_code ModularizeUtilities::loadSingleHeaderListsAndDependencies(
    llvm::StringRef InputPath) {

  // By default, use the path component of the list file name.
  SmallString<256> HeaderDirectory(InputPath);
  llvm::sys::path::remove_filename(HeaderDirectory);
  SmallString<256> CurrentDirectory;
  llvm::sys::fs::current_path(CurrentDirectory);

  // Get the prefix if we have one.
  if (HeaderPrefix.size() != 0)
    HeaderDirectory = HeaderPrefix;

  // Read the header list file into a buffer.
  ErrorOr<std::unique_ptr<MemoryBuffer>> listBuffer =
    MemoryBuffer::getFile(InputPath);
  if (std::error_code EC = listBuffer.getError())
    return EC;

  // Parse the header list into strings.
  SmallVector<StringRef, 32> Strings;
  listBuffer.get()->getBuffer().split(Strings, "\n", -1, false);

  // Collect the header file names from the string list.
  for (SmallVectorImpl<StringRef>::iterator I = Strings.begin(),
    E = Strings.end();
    I != E; ++I) {
    StringRef Line = I->trim();
    // Ignore comments and empty lines.
    if (Line.empty() || (Line[0] == '#'))
      continue;
    std::pair<StringRef, StringRef> TargetAndDependents = Line.split(':');
    SmallString<256> HeaderFileName;
    // Prepend header file name prefix if it's not absolute.
    if (llvm::sys::path::is_absolute(TargetAndDependents.first))
      llvm::sys::path::native(TargetAndDependents.first, HeaderFileName);
    else {
      if (HeaderDirectory.size() != 0)
        HeaderFileName = HeaderDirectory;
      else
        HeaderFileName = CurrentDirectory;
      llvm::sys::path::append(HeaderFileName, TargetAndDependents.first);
      llvm::sys::path::native(HeaderFileName);
    }
    // Handle optional dependencies.
    DependentsVector Dependents;
    SmallVector<StringRef, 4> DependentsList;
    TargetAndDependents.second.split(DependentsList, " ", -1, false);
    int Count = DependentsList.size();
    for (int Index = 0; Index < Count; ++Index) {
      SmallString<256> Dependent;
      if (llvm::sys::path::is_absolute(DependentsList[Index]))
        Dependent = DependentsList[Index];
      else {
        if (HeaderDirectory.size() != 0)
          Dependent = HeaderDirectory;
        else
          Dependent = CurrentDirectory;
        llvm::sys::path::append(Dependent, DependentsList[Index]);
      }
      llvm::sys::path::native(Dependent);
      Dependents.push_back(getCanonicalPath(Dependent.str()));
    }
    // Get canonical form.
    HeaderFileName = getCanonicalPath(HeaderFileName);
    // Save the resulting header file path and dependencies.
    HeaderFileNames.push_back(std::string(HeaderFileName.str()));
    Dependencies[HeaderFileName.str()] = Dependents;
  }
  return std::error_code();
}

// Load problem header list.
std::error_code ModularizeUtilities::loadProblemHeaderList(
  llvm::StringRef InputPath) {

  // By default, use the path component of the list file name.
  SmallString<256> HeaderDirectory(InputPath);
  llvm::sys::path::remove_filename(HeaderDirectory);
  SmallString<256> CurrentDirectory;
  llvm::sys::fs::current_path(CurrentDirectory);

  // Get the prefix if we have one.
  if (HeaderPrefix.size() != 0)
    HeaderDirectory = HeaderPrefix;

  // Read the header list file into a buffer.
  ErrorOr<std::unique_ptr<MemoryBuffer>> listBuffer =
    MemoryBuffer::getFile(InputPath);
  if (std::error_code EC = listBuffer.getError())
    return EC;

  // Parse the header list into strings.
  SmallVector<StringRef, 32> Strings;
  listBuffer.get()->getBuffer().split(Strings, "\n", -1, false);

  // Collect the header file names from the string list.
  for (SmallVectorImpl<StringRef>::iterator I = Strings.begin(),
    E = Strings.end();
    I != E; ++I) {
    StringRef Line = I->trim();
    // Ignore comments and empty lines.
    if (Line.empty() || (Line[0] == '#'))
      continue;
    SmallString<256> HeaderFileName;
    // Prepend header file name prefix if it's not absolute.
    if (llvm::sys::path::is_absolute(Line))
      llvm::sys::path::native(Line, HeaderFileName);
    else {
      if (HeaderDirectory.size() != 0)
        HeaderFileName = HeaderDirectory;
      else
        HeaderFileName = CurrentDirectory;
      llvm::sys::path::append(HeaderFileName, Line);
      llvm::sys::path::native(HeaderFileName);
    }
    // Get canonical form.
    HeaderFileName = getCanonicalPath(HeaderFileName);
    // Save the resulting header file path.
    ProblemFileNames.push_back(std::string(HeaderFileName.str()));
  }
  return std::error_code();
}

// Load single module map and extract header file list.
std::error_code ModularizeUtilities::loadModuleMap(
    llvm::StringRef InputPath) {
  // Get file entry for module.modulemap file.
  auto ModuleMapEntryOrErr =
    SourceMgr->getFileManager().getFile(InputPath);

  // return error if not found.
  if (!ModuleMapEntryOrErr) {
    llvm::errs() << "error: File \"" << InputPath << "\" not found.\n";
    return ModuleMapEntryOrErr.getError();
  }
  const FileEntry *ModuleMapEntry = *ModuleMapEntryOrErr;

  // Because the module map parser uses a ForwardingDiagnosticConsumer,
  // which doesn't forward the BeginSourceFile call, we do it explicitly here.
  DC.BeginSourceFile(*LangOpts, nullptr);

  // Figure out the home directory for the module map file.
  const DirectoryEntry *Dir = ModuleMapEntry->getDir();
  StringRef DirName(Dir->getName());
  if (llvm::sys::path::filename(DirName) == "Modules") {
    DirName = llvm::sys::path::parent_path(DirName);
    if (DirName.endswith(".framework")) {
      if (auto DirEntry = FileMgr->getDirectory(DirName))
        Dir = *DirEntry;
      else
        Dir = nullptr;
    }
    // FIXME: This assert can fail if there's a race between the above check
    // and the removal of the directory.
    assert(Dir && "parent must exist");
  }

  std::unique_ptr<ModuleMap> ModMap;
  ModMap.reset(new ModuleMap(*SourceMgr, *Diagnostics, *LangOpts,
    Target.get(), *HeaderInfo));

  // Parse module.modulemap file into module map.
  if (ModMap->parseModuleMapFile(ModuleMapEntry, false, Dir)) {
    return std::error_code(1, std::generic_category());
  }

  // Do matching end call.
  DC.EndSourceFile();

  // Reset missing header count.
  MissingHeaderCount = 0;

  if (!collectModuleMapHeaders(ModMap.get()))
    return std::error_code(1, std::generic_category());

  // Save module map.
  ModuleMaps.push_back(std::move(ModMap));

  // Indicate we are using module maps.
  HasModuleMap = true;

  // Return code of 1 for missing headers.
  if (MissingHeaderCount)
    return std::error_code(1, std::generic_category());

  return std::error_code();
}

// Collect module map headers.
// Walks the modules and collects referenced headers into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleMapHeaders(clang::ModuleMap *ModMap) {
  for (ModuleMap::module_iterator I = ModMap->module_begin(),
    E = ModMap->module_end();
    I != E; ++I) {
    if (!collectModuleHeaders(*I->second))
      return false;
  }
  return true;
}

// Collect referenced headers from one module.
// Collects the headers referenced in the given module into
// HeaderFileNames.
bool ModularizeUtilities::collectModuleHeaders(const clang::Module &Mod) {

  // Ignore explicit modules because they often have dependencies
  // we can't know.
  if (Mod.IsExplicit)
    return true;

  // Treat headers in umbrella directory as dependencies.
  DependentsVector UmbrellaDependents;

  // Recursively do submodules.
  for (auto MI = Mod.submodule_begin(), MIEnd = Mod.submodule_end();
       MI != MIEnd; ++MI)
    collectModuleHeaders(**MI);

  if (const FileEntry *UmbrellaHeader = Mod.getUmbrellaHeader().Entry) {
    std::string HeaderPath = getCanonicalPath(UmbrellaHeader->getName());
    // Collect umbrella header.
    HeaderFileNames.push_back(HeaderPath);

    // FUTURE: When needed, umbrella header header collection goes here.
  }
  else if (const DirectoryEntry *UmbrellaDir = Mod.getUmbrellaDir().Entry) {
    // If there normal headers, assume these are umbrellas and skip collection.
    if (Mod.Headers->size() == 0) {
      // Collect headers in umbrella directory.
      if (!collectUmbrellaHeaders(UmbrellaDir->getName(), UmbrellaDependents))
        return false;
    }
  }

  // We ignore HK_Private, HK_Textual, HK_PrivateTextual, and HK_Excluded,
  // assuming they are marked as such either because of unsuitability for
  // modules or because they are meant to be included by another header,
  // and thus should be ignored by modularize.

  int NormalHeaderCount = Mod.Headers[clang::Module::HK_Normal].size();

  for (int Index = 0; Index < NormalHeaderCount; ++Index) {
    DependentsVector NormalDependents;
    // Collect normal header.
    const clang::Module::Header &Header(
      Mod.Headers[clang::Module::HK_Normal][Index]);
    std::string HeaderPath = getCanonicalPath(Header.Entry->getName());
    HeaderFileNames.push_back(HeaderPath);
  }

  int MissingCountThisModule = Mod.MissingHeaders.size();

  for (int Index = 0; Index < MissingCountThisModule; ++Index) {
    std::string MissingFile = Mod.MissingHeaders[Index].FileName;
    SourceLocation Loc = Mod.MissingHeaders[Index].FileNameLoc;
    errs() << Loc.printToString(*SourceMgr)
      << ": error : Header not found: " << MissingFile << "\n";
  }

  MissingHeaderCount += MissingCountThisModule;

  return true;
}

// Collect headers from an umbrella directory.
bool ModularizeUtilities::collectUmbrellaHeaders(StringRef UmbrellaDirName,
  DependentsVector &Dependents) {
  // Initialize directory name.
  SmallString<256> Directory(UmbrellaDirName);
  // Walk the directory.
  std::error_code EC;
  for (llvm::sys::fs::directory_iterator I(Directory.str(), EC), E; I != E;
    I.increment(EC)) {
    if (EC)
      return false;
    std::string File(I->path());
    llvm::ErrorOr<llvm::sys::fs::basic_file_status> Status = I->status();
    if (!Status)
      return false;
    llvm::sys::fs::file_type Type = Status->type();
    // If the file is a directory, ignore the name and recurse.
    if (Type == llvm::sys::fs::file_type::directory_file) {
      if (!collectUmbrellaHeaders(File, Dependents))
        return false;
      continue;
    }
    // If the file does not have a common header extension, ignore it.
    if (!isHeader(File))
      continue;
    // Save header name.
    std::string HeaderPath = getCanonicalPath(File);
    Dependents.push_back(HeaderPath);
  }
  return true;
}

// Replace .. embedded in path for purposes of having
// a canonical path.
static std::string replaceDotDot(StringRef Path) {
  SmallString<128> Buffer;
  llvm::sys::path::const_iterator B = llvm::sys::path::begin(Path),
    E = llvm::sys::path::end(Path);
  while (B != E) {
    if (B->compare(".") == 0) {
    }
    else if (B->compare("..") == 0)
      llvm::sys::path::remove_filename(Buffer);
    else
      llvm::sys::path::append(Buffer, *B);
    ++B;
  }
  if (Path.endswith("/") || Path.endswith("\\"))
    Buffer.append(1, Path.back());
  return Buffer.c_str();
}

// Convert header path to canonical form.
// The canonical form is basically just use forward slashes, and remove "./".
// \param FilePath The file path, relative to the module map directory.
// \returns The file path in canonical form.
std::string ModularizeUtilities::getCanonicalPath(StringRef FilePath) {
  std::string Tmp(replaceDotDot(FilePath));
  std::replace(Tmp.begin(), Tmp.end(), '\\', '/');
  StringRef Tmp2(Tmp);
  if (Tmp2.startswith("./"))
    Tmp = std::string(Tmp2.substr(2));
  return Tmp;
}

// Check for header file extension.
// If the file extension is .h, .inc, or missing, it's
// assumed to be a header.
// \param FileName The file name.  Must not be a directory.
// \returns true if it has a header extension or no extension.
bool ModularizeUtilities::isHeader(StringRef FileName) {
  StringRef Extension = llvm::sys::path::extension(FileName);
  if (Extension.size() == 0)
    return true;
  if (Extension.equals_insensitive(".h"))
    return true;
  if (Extension.equals_insensitive(".inc"))
    return true;
  return false;
}

// Get directory path component from file path.
// \returns the component of the given path, which will be
// relative if the given path is relative, absolute if the
// given path is absolute, or "." if the path has no leading
// path component.
std::string ModularizeUtilities::getDirectoryFromPath(StringRef Path) {
  SmallString<256> Directory(Path);
  sys::path::remove_filename(Directory);
  if (Directory.size() == 0)
    return ".";
  return std::string(Directory.str());
}

// Add unique problem file.
// Also standardizes the path.
void ModularizeUtilities::addUniqueProblemFile(std::string FilePath) {
  FilePath = getCanonicalPath(FilePath);
  // Don't add if already present.
  for(auto &TestFilePath : ProblemFileNames) {
    if (TestFilePath == FilePath)
      return;
  }
  ProblemFileNames.push_back(FilePath);
}

// Add file with no compile errors.
// Also standardizes the path.
void ModularizeUtilities::addNoCompileErrorsFile(std::string FilePath) {
  FilePath = getCanonicalPath(FilePath);
  GoodFileNames.push_back(FilePath);
}

// List problem files.
void ModularizeUtilities::displayProblemFiles() {
  errs() << "\nThese are the files with possible errors:\n\n";
  for (auto &ProblemFile : ProblemFileNames) {
    errs() << ProblemFile << "\n";
  }
}

// List files with no problems.
void ModularizeUtilities::displayGoodFiles() {
  errs() << "\nThese are the files with no detected errors:\n\n";
  for (auto &GoodFile : HeaderFileNames) {
    bool Good = true;
    for (auto &ProblemFile : ProblemFileNames) {
      if (ProblemFile == GoodFile) {
        Good = false;
        break;
      }
    }
    if (Good)
      errs() << GoodFile << "\n";
  }
}

// List files with problem files commented out.
void ModularizeUtilities::displayCombinedFiles() {
  errs() <<
    "\nThese are the combined files, with problem files preceded by #:\n\n";
  for (auto &File : HeaderFileNames) {
    bool Good = true;
    for (auto &ProblemFile : ProblemFileNames) {
      if (ProblemFile == File) {
        Good = false;
        break;
      }
    }
    errs() << (Good ? "" : "#") << File << "\n";
  }
}
