//===--- ModuleDependencyCollector.cpp - Collect module dependencies ------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Collect the dependencies of a set of modules.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/Utils.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;

namespace {
/// Private implementation for ModuleDependencyCollector
class ModuleDependencyListener : public ASTReaderListener {
  ModuleDependencyCollector &Collector;

  std::error_code copyToRoot(StringRef Src);
public:
  ModuleDependencyListener(ModuleDependencyCollector &Collector)
      : Collector(Collector) {}
  bool needsInputFileVisitation() override { return true; }
  bool needsSystemInputFileVisitation() override { return true; }
  bool visitInputFile(StringRef Filename, bool IsSystem,
                      bool IsOverridden) override;
};
}

void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
  R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
}

void ModuleDependencyCollector::writeFileMap() {
  if (Seen.empty())
    return;

  SmallString<256> Dest = getDest();
  llvm::sys::path::append(Dest, "vfs.yaml");

  std::error_code EC;
  llvm::raw_fd_ostream OS(Dest, EC, llvm::sys::fs::F_Text);
  if (EC) {
    setHasErrors();
    return;
  }
  VFSWriter.write(OS);
}

/// Remove traversal (ie, . or ..) from the given absolute path.
static void removePathTraversal(SmallVectorImpl<char> &Path) {
  using namespace llvm::sys;
  SmallVector<StringRef, 16> ComponentStack;
  StringRef P(Path.data(), Path.size());

  // Skip the root path, then look for traversal in the components.
  StringRef Rel = path::relative_path(P);
  for (StringRef C : llvm::make_range(path::begin(Rel), path::end(Rel))) {
    if (C == ".")
      continue;
    if (C == "..") {
      assert(ComponentStack.size() && "Path traverses out of parent");
      ComponentStack.pop_back();
    } else
      ComponentStack.push_back(C);
  }

  // The stack is now the path without any directory traversal.
  SmallString<256> Buffer = path::root_path(P);
  for (StringRef C : ComponentStack)
    path::append(Buffer, C);

  // Put the result in Path.
  Path.swap(Buffer);
}

std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
  using namespace llvm::sys;

  // We need an absolute path to append to the root.
  SmallString<256> AbsoluteSrc = Src;
  fs::make_absolute(AbsoluteSrc);
  removePathTraversal(AbsoluteSrc);

  // Build the destination path.
  SmallString<256> Dest = Collector.getDest();
  path::append(Dest, path::relative_path(AbsoluteSrc));

  // Copy the file into place.
  if (std::error_code EC = fs::create_directories(path::parent_path(Dest),
                                                   /*IgnoreExisting=*/true))
    return EC;
  if (std::error_code EC = fs::copy_file(AbsoluteSrc.str(), Dest.str()))
    return EC;
  // Use the absolute path under the root for the file mapping.
  Collector.addFileMapping(AbsoluteSrc.str(), Dest.str());
  return std::error_code();
}

bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem,
                                              bool IsOverridden) {
  if (Collector.insertSeen(Filename))
    if (copyToRoot(Filename))
      Collector.setHasErrors();
  return true;
}
