//===--- ModuleAssistant.cpp - Module map generation manager -*- C++ -*---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
//
// This file defines the module generation entry point function,
// createModuleMap, a Module class for representing a module,
// and various implementation functions for doing the underlying
// work, described below.
//
// The "Module" class represents a module, with members for storing the module
// name, associated header file names, and sub-modules, and an "output"
// function that recursively writes the module definitions.
//
// The "createModuleMap" function implements the top-level logic of the
// assistant mode.  It calls a loadModuleDescriptions function to walk
// the header list passed to it and creates a tree of Module objects
// representing the module hierarchy, represented by a "Module" object,
// the "RootModule".  This root module may or may not represent an actual
// module in the module map, depending on the "--root-module" option passed
// to modularize.  It then calls a writeModuleMap function to set up the
// module map file output and walk the module tree, outputting the module
// map file using a stream obtained and managed by an
// llvm::ToolOutputFile object.
//
//===---------------------------------------------------------------------===//

#include "Modularize.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ToolOutputFile.h"
#include <vector>

// Local definitions:

namespace {

// Internal class definitions:

// Represents a module.
class Module {
public:
  Module(llvm::StringRef Name, bool Problem);
  Module();
  ~Module();
  bool output(llvm::raw_fd_ostream &OS, int Indent);
  Module *findSubModule(llvm::StringRef SubName);

public:
  std::string Name;
  std::vector<std::string> HeaderFileNames;
  std::vector<Module *> SubModules;
  bool IsProblem;
};

} // end anonymous namespace.

// Module functions:

// Constructors.
Module::Module(llvm::StringRef Name, bool Problem)
  : Name(Name), IsProblem(Problem) {}
Module::Module() : IsProblem(false) {}

// Destructor.
Module::~Module() {
  // Free submodules.
  while (!SubModules.empty()) {
    Module *last = SubModules.back();
    SubModules.pop_back();
    delete last;
  }
}

// Write a module hierarchy to the given output stream.
bool Module::output(llvm::raw_fd_ostream &OS, int Indent) {
  // If this is not the nameless root module, start a module definition.
  if (Name.size() != 0) {
    OS.indent(Indent);
    OS << "module " << Name << " {\n";
    Indent += 2;
  }

  // Output submodules.
  for (auto I = SubModules.begin(), E = SubModules.end(); I != E; ++I) {
    if (!(*I)->output(OS, Indent))
      return false;
  }

  // Output header files.
  for (auto I = HeaderFileNames.begin(), E = HeaderFileNames.end(); I != E;
       ++I) {
    OS.indent(Indent);
    if (IsProblem || strstr((*I).c_str(), ".inl"))
      OS << "exclude header \"" << *I << "\"\n";
    else
      OS << "header \"" << *I << "\"\n";
  }

  // If this module has header files, output export directive.
  if (HeaderFileNames.size() != 0) {
    OS.indent(Indent);
    OS << "export *\n";
  }

  // If this is not the nameless root module, close the module definition.
  if (Name.size() != 0) {
    Indent -= 2;
    OS.indent(Indent);
    OS << "}\n";
  }

  return true;
}

// Lookup a sub-module.
Module *Module::findSubModule(llvm::StringRef SubName) {
  for (auto I = SubModules.begin(), E = SubModules.end(); I != E; ++I) {
    if ((*I)->Name == SubName)
      return *I;
  }
  return nullptr;
}

// Implementation functions:

// Reserved keywords in module.modulemap syntax.
// Keep in sync with keywords in module map parser in Lex/ModuleMap.cpp,
// such as in ModuleMapParser::consumeToken().
static const char *const ReservedNames[] = {
  "config_macros", "export",   "module", "conflict", "framework",
  "requires",      "exclude",  "header", "private",  "explicit",
  "link",          "umbrella", "extern", "use",      nullptr // Flag end.
};

// Convert module name to a non-keyword.
// Prepends a '_' to the name if and only if the name is a keyword.
static std::string
ensureNoCollisionWithReservedName(llvm::StringRef MightBeReservedName) {
  std::string SafeName = MightBeReservedName;
  for (int Index = 0; ReservedNames[Index] != nullptr; ++Index) {
    if (MightBeReservedName == ReservedNames[Index]) {
      SafeName.insert(0, "_");
      break;
    }
  }
  return SafeName;
}

// Convert module name to a non-keyword.
// Prepends a '_' to the name if and only if the name is a keyword.
static std::string
ensureVaidModuleName(llvm::StringRef MightBeInvalidName) {
  std::string SafeName = MightBeInvalidName;
  std::replace(SafeName.begin(), SafeName.end(), '-', '_');
  std::replace(SafeName.begin(), SafeName.end(), '.', '_');
  if (isdigit(SafeName[0]))
    SafeName = "_" + SafeName;
  return SafeName;
}

// Add one module, given a header file path.
static bool addModuleDescription(Module *RootModule,
                                 llvm::StringRef HeaderFilePath,
                                 llvm::StringRef HeaderPrefix,
                                 DependencyMap &Dependencies,
                                 bool IsProblemFile) {
  Module *CurrentModule = RootModule;
  DependentsVector &FileDependents = Dependencies[HeaderFilePath];
  std::string FilePath;
  // Strip prefix.
  // HeaderFilePath should be compared to natively-canonicalized Prefix.
  llvm::SmallString<256> NativePath, NativePrefix;
  llvm::sys::path::native(HeaderFilePath, NativePath);
  llvm::sys::path::native(HeaderPrefix, NativePrefix);
  if (NativePath.startswith(NativePrefix))
    FilePath = NativePath.substr(NativePrefix.size() + 1);
  else
    FilePath = HeaderFilePath;
  int Count = FileDependents.size();
  // Headers that go into modules must not depend on other files being
  // included first.  If there are any dependents, warn user and omit.
  if (Count != 0) {
    llvm::errs() << "warning: " << FilePath
                 << " depends on other headers being included first,"
                    " meaning the module.modulemap won't compile."
                    "  This header will be omitted from the module map.\n";
    return true;
  }
  // Make canonical.
  std::replace(FilePath.begin(), FilePath.end(), '\\', '/');
  // Insert module into tree, using subdirectories as submodules.
  for (llvm::sys::path::const_iterator I = llvm::sys::path::begin(FilePath),
                                       E = llvm::sys::path::end(FilePath);
       I != E; ++I) {
    if ((*I)[0] == '.')
      continue;
    std::string Stem = llvm::sys::path::stem(*I);
    Stem = ensureNoCollisionWithReservedName(Stem);
    Stem = ensureVaidModuleName(Stem);
    Module *SubModule = CurrentModule->findSubModule(Stem);
    if (!SubModule) {
      SubModule = new Module(Stem, IsProblemFile);
      CurrentModule->SubModules.push_back(SubModule);
    }
    CurrentModule = SubModule;
  }
  // Add header file name to headers.
  CurrentModule->HeaderFileNames.push_back(FilePath);
  return true;
}

// Create the internal module tree representation.
static Module *loadModuleDescriptions(
    llvm::StringRef RootModuleName, llvm::ArrayRef<std::string> HeaderFileNames,
    llvm::ArrayRef<std::string> ProblemFileNames,
    DependencyMap &Dependencies, llvm::StringRef HeaderPrefix) {

  // Create root module.
  auto *RootModule = new Module(RootModuleName, false);

  llvm::SmallString<256> CurrentDirectory;
  llvm::sys::fs::current_path(CurrentDirectory);

  // If no header prefix, use current directory.
  if (HeaderPrefix.size() == 0)
    HeaderPrefix = CurrentDirectory;

  // Walk the header file names and output the module map.
  for (llvm::ArrayRef<std::string>::iterator I = HeaderFileNames.begin(),
                                             E = HeaderFileNames.end();
       I != E; ++I) {
    std::string Header(*I);
    bool IsProblemFile = false;
    for (auto &ProblemFile : ProblemFileNames) {
      if (ProblemFile == Header) {
        IsProblemFile = true;
        break;
      }
    }
    // Add as a module.
    if (!addModuleDescription(RootModule, Header, HeaderPrefix, Dependencies, IsProblemFile))
      return nullptr;
  }

  return RootModule;
}

// Kick off the writing of the module map.
static bool writeModuleMap(llvm::StringRef ModuleMapPath,
                           llvm::StringRef HeaderPrefix, Module *RootModule) {
  llvm::SmallString<256> HeaderDirectory(ModuleMapPath);
  llvm::sys::path::remove_filename(HeaderDirectory);
  llvm::SmallString<256> FilePath;

  // Get the module map file path to be used.
  if ((HeaderDirectory.size() == 0) && (HeaderPrefix.size() != 0)) {
    FilePath = HeaderPrefix;
    // Prepend header file name prefix if it's not absolute.
    llvm::sys::path::append(FilePath, ModuleMapPath);
    llvm::sys::path::native(FilePath);
  } else {
    FilePath = ModuleMapPath;
    llvm::sys::path::native(FilePath);
  }

  // Set up module map output file.
  std::error_code EC;
  llvm::ToolOutputFile Out(FilePath, EC, llvm::sys::fs::F_Text);
  if (EC) {
    llvm::errs() << Argv0 << ": error opening " << FilePath << ":"
                 << EC.message() << "\n";
    return false;
  }

  // Get output stream from tool output buffer/manager.
  llvm::raw_fd_ostream &OS = Out.os();

  // Output file comment.
  OS << "// " << ModuleMapPath << "\n";
  OS << "// Generated by: " << CommandLine << "\n\n";

  // Write module hierarchy from internal representation.
  if (!RootModule->output(OS, 0))
    return false;

  // Tell ToolOutputFile that we want to keep the file.
  Out.keep();

  return true;
}

// Global functions:

// Module map generation entry point.
bool createModuleMap(llvm::StringRef ModuleMapPath,
                     llvm::ArrayRef<std::string> HeaderFileNames,
                     llvm::ArrayRef<std::string> ProblemFileNames,
                     DependencyMap &Dependencies, llvm::StringRef HeaderPrefix,
                     llvm::StringRef RootModuleName) {
  // Load internal representation of modules.
  std::unique_ptr<Module> RootModule(
    loadModuleDescriptions(
      RootModuleName, HeaderFileNames, ProblemFileNames, Dependencies,
      HeaderPrefix));
  if (!RootModule.get())
    return false;

  // Write module map file.
  return writeModuleMap(ModuleMapPath, HeaderPrefix, RootModule.get());
}
