//===-- ClangDocMain.cpp - ClangDoc -----------------------------*- C++ -*-===//
//
// 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 tool for generating C and C++ documentation from source code
// and comments. Generally, it runs a LibTooling FrontendAction on source files,
// mapping each declaration in those files to its USR and serializing relevant
// information into LLVM bitcode. It then runs a pass over the collected
// declaration information, reducing by USR. There is an option to dump this
// intermediate result to bitcode. Finally, it hands the reduced information
// off to a generator, which does the final parsing from the intermediate
// representation to the desired output format.
//
//===----------------------------------------------------------------------===//

#include "BitcodeReader.h"
#include "BitcodeWriter.h"
#include "ClangDoc.h"
#include "Generators.h"
#include "Representation.h"
#include "clang/AST/AST.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Tooling/AllTUsExecution.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Execution.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/raw_ostream.h"
#include <atomic>
#include <string>

using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace clang;

static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
static llvm::cl::OptionCategory ClangDocCategory("clang-doc options");

static llvm::cl::opt<std::string>
    ProjectName("project-name", llvm::cl::desc("Name of project."),
                llvm::cl::cat(ClangDocCategory));

static llvm::cl::opt<bool> IgnoreMappingFailures(
    "ignore-map-errors",
    llvm::cl::desc("Continue if files are not mapped correctly."),
    llvm::cl::init(true), llvm::cl::cat(ClangDocCategory));

static llvm::cl::opt<std::string>
    OutDirectory("output",
                 llvm::cl::desc("Directory for outputting generated files."),
                 llvm::cl::init("docs"), llvm::cl::cat(ClangDocCategory));

static llvm::cl::opt<bool>
    PublicOnly("public", llvm::cl::desc("Document only public declarations."),
               llvm::cl::init(false), llvm::cl::cat(ClangDocCategory));

static llvm::cl::opt<bool> DoxygenOnly(
    "doxygen",
    llvm::cl::desc("Use only doxygen-style comments to generate docs."),
    llvm::cl::init(false), llvm::cl::cat(ClangDocCategory));

static llvm::cl::list<std::string> UserStylesheets(
    "stylesheets", llvm::cl::CommaSeparated,
    llvm::cl::desc("CSS stylesheets to extend the default styles."),
    llvm::cl::cat(ClangDocCategory));

static llvm::cl::opt<std::string> SourceRoot("source-root", llvm::cl::desc(R"(
Directory where processed files are stored.
Links to definition locations will only be
generated if the file is in this dir.)"),
                                             llvm::cl::cat(ClangDocCategory));

static llvm::cl::opt<std::string>
    RepositoryUrl("repository", llvm::cl::desc(R"(
URL of repository that hosts code.
Used for links to definition locations.)"),
                  llvm::cl::cat(ClangDocCategory));

enum OutputFormatTy {
  md,
  yaml,
  html,
};

static llvm::cl::opt<OutputFormatTy>
    FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
               llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
                                           "Documentation in YAML format."),
                                clEnumValN(OutputFormatTy::md, "md",
                                           "Documentation in MD format."),
                                clEnumValN(OutputFormatTy::html, "html",
                                           "Documentation in HTML format.")),
               llvm::cl::init(OutputFormatTy::yaml),
               llvm::cl::cat(ClangDocCategory));

std::string getFormatString() {
  switch (FormatEnum) {
  case OutputFormatTy::yaml:
    return "yaml";
  case OutputFormatTy::md:
    return "md";
  case OutputFormatTy::html:
    return "html";
  }
  llvm_unreachable("Unknown OutputFormatTy");
}

// This function isn't referenced outside its translation unit, but it
// can't use the "static" keyword because its address is used for
// GetMainExecutable (since some platforms don't support taking the
// address of main, and some platforms can't implement GetMainExecutable
// without being given the address of a function in the main executable).
std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
  return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
}

bool CreateDirectory(const Twine &DirName, bool ClearDirectory = false) {
  std::error_code OK;
  llvm::SmallString<128> DocsRootPath;
  if (ClearDirectory) {
    std::error_code RemoveStatus = llvm::sys::fs::remove_directories(DirName);
    if (RemoveStatus != OK) {
      llvm::errs() << "Unable to remove existing documentation directory for "
                   << DirName << ".\n";
      return true;
    }
  }
  std::error_code DirectoryStatus = llvm::sys::fs::create_directories(DirName);
  if (DirectoryStatus != OK) {
    llvm::errs() << "Unable to create documentation directories.\n";
    return true;
  }
  return false;
}

// A function to extract the appropriate file name for a given info's
// documentation. The path returned is a composite of the output directory, the
// info's relative path and name and the extension. The relative path should
// have been constructed in the serialization phase.
//
// Example: Given the below, the <ext> path for class C will be
// <root>/A/B/C.<ext>
//
// namespace A {
// namespace B {
//
// class C {};
//
// }
// }
llvm::Expected<llvm::SmallString<128>> getInfoOutputFile(StringRef Root,
                                                         StringRef RelativePath,
                                                         StringRef Name,
                                                         StringRef Ext) {
  llvm::SmallString<128> Path;
  llvm::sys::path::native(Root, Path);
  llvm::sys::path::append(Path, RelativePath);
  if (CreateDirectory(Path))
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "failed to create directory");
  llvm::sys::path::append(Path, Name + Ext);
  return Path;
}

int main(int argc, const char **argv) {
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  std::error_code OK;

  ExecutorName.setInitialValue("all-TUs");
  auto Exec = clang::tooling::createExecutorFromCommandLineArgs(
      argc, argv, ClangDocCategory);

  if (!Exec) {
    llvm::errs() << toString(Exec.takeError()) << "\n";
    return 1;
  }

  // Fail early if an invalid format was provided.
  std::string Format = getFormatString();
  llvm::outs() << "Emiting docs in " << Format << " format.\n";
  auto G = doc::findGeneratorByName(Format);
  if (!G) {
    llvm::errs() << toString(G.takeError()) << "\n";
    return 1;
  }

  ArgumentsAdjuster ArgAdjuster;
  if (!DoxygenOnly)
    ArgAdjuster = combineAdjusters(
        getInsertArgumentAdjuster("-fparse-all-comments",
                                  tooling::ArgumentInsertPosition::END),
        ArgAdjuster);

  clang::doc::ClangDocContext CDCtx = {
      Exec->get()->getExecutionContext(),
      ProjectName,
      PublicOnly,
      OutDirectory,
      SourceRoot,
      RepositoryUrl,
      {UserStylesheets.begin(), UserStylesheets.end()},
      {"index.js", "index_json.js"}};

  if (Format == "html") {
    void *MainAddr = (void *)(intptr_t)GetExecutablePath;
    std::string ClangDocPath = GetExecutablePath(argv[0], MainAddr);
    llvm::SmallString<128> AssetsPath;
    llvm::sys::path::native(ClangDocPath, AssetsPath);
    AssetsPath = llvm::sys::path::parent_path(AssetsPath);
    llvm::sys::path::append(AssetsPath, "..", "share", "clang");
    llvm::SmallString<128> DefaultStylesheet;
    llvm::sys::path::native(AssetsPath, DefaultStylesheet);
    llvm::sys::path::append(DefaultStylesheet,
                            "clang-doc-default-stylesheet.css");
    llvm::SmallString<128> IndexJS;
    llvm::sys::path::native(AssetsPath, IndexJS);
    llvm::sys::path::append(IndexJS, "index.js");
    CDCtx.UserStylesheets.insert(CDCtx.UserStylesheets.begin(),
                                 std::string(DefaultStylesheet.str()));
    CDCtx.FilesToCopy.emplace_back(IndexJS.str());
  }

  // Mapping phase
  llvm::outs() << "Mapping decls...\n";
  auto Err =
      Exec->get()->execute(doc::newMapperActionFactory(CDCtx), ArgAdjuster);
  if (Err) {
    if (IgnoreMappingFailures)
      llvm::errs() << "Error mapping decls in files. Clang-doc will ignore "
                      "these files and continue:\n"
                   << toString(std::move(Err)) << "\n";
    else {
      llvm::errs() << toString(std::move(Err)) << "\n";
      return 1;
    }
  }

  // Collect values into output by key.
  // In ToolResults, the Key is the hashed USR and the value is the
  // bitcode-encoded representation of the Info object.
  llvm::outs() << "Collecting infos...\n";
  llvm::StringMap<std::vector<StringRef>> USRToBitcode;
  Exec->get()->getToolResults()->forEachResult(
      [&](StringRef Key, StringRef Value) {
        auto R = USRToBitcode.try_emplace(Key, std::vector<StringRef>());
        R.first->second.emplace_back(Value);
      });

  // First reducing phase (reduce all decls into one info per decl).
  llvm::outs() << "Reducing " << USRToBitcode.size() << " infos...\n";
  std::atomic<bool> Error;
  Error = false;
  llvm::sys::Mutex IndexMutex;
  // ExecutorConcurrency is a flag exposed by AllTUsExecution.h
  llvm::ThreadPool Pool(llvm::hardware_concurrency(ExecutorConcurrency));
  for (auto &Group : USRToBitcode) {
    Pool.async([&]() {
      std::vector<std::unique_ptr<doc::Info>> Infos;

      for (auto &Bitcode : Group.getValue()) {
        llvm::BitstreamCursor Stream(Bitcode);
        doc::ClangDocBitcodeReader Reader(Stream);
        auto ReadInfos = Reader.readBitcode();
        if (!ReadInfos) {
          llvm::errs() << toString(ReadInfos.takeError()) << "\n";
          Error = true;
          return;
        }
        std::move(ReadInfos->begin(), ReadInfos->end(),
                  std::back_inserter(Infos));
      }

      auto Reduced = doc::mergeInfos(Infos);
      if (!Reduced) {
        llvm::errs() << llvm::toString(Reduced.takeError());
        return;
      }

      doc::Info *I = Reduced.get().get();
      auto InfoPath =
          getInfoOutputFile(OutDirectory, I->getRelativeFilePath(""),
                            I->getFileBaseName(), "." + Format);
      if (!InfoPath) {
        llvm::errs() << toString(InfoPath.takeError()) << "\n";
        Error = true;
        return;
      }
      std::error_code FileErr;
      llvm::raw_fd_ostream InfoOS(InfoPath.get(), FileErr,
                                  llvm::sys::fs::OF_None);
      if (FileErr) {
        llvm::errs() << "Error opening info file " << InfoPath.get() << ": "
                     << FileErr.message() << "\n";
        return;
      }

      IndexMutex.lock();
      // Add a reference to this Info in the Index
      clang::doc::Generator::addInfoToIndex(CDCtx.Idx, I);
      IndexMutex.unlock();

      if (auto Err = G->get()->generateDocForInfo(I, InfoOS, CDCtx))
        llvm::errs() << toString(std::move(Err)) << "\n";
    });
  }

  Pool.wait();

  if (Error)
    return 1;

  llvm::outs() << "Generating assets for docs...\n";
  Err = G->get()->createResources(CDCtx);
  if (Err) {
    llvm::errs() << toString(std::move(Err)) << "\n";
    return 1;
  }

  return 0;
}
