//===-- llvm-readtapi.cpp - tapi file reader and transformer -----*- 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 file defines the command-line driver for llvm-readtapi.
//
//===----------------------------------------------------------------------===//
#include "DiffEngine.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Driver.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TextAPI/DylibReader.h"
#include "llvm/TextAPI/TextAPIError.h"
#include "llvm/TextAPI/TextAPIReader.h"
#include "llvm/TextAPI/TextAPIWriter.h"
#include "llvm/TextAPI/Utils.h"
#include <cstdlib>

#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
#endif

using namespace llvm;
using namespace MachO;
using namespace object;

namespace {
using namespace llvm::opt;
enum ID {
  OPT_INVALID = 0, // This is not an option ID.
#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
#include "TapiOpts.inc"
#undef OPTION
};

#define OPTTABLE_CODE
#include "TapiOpts.inc"

class TAPIOptTable : public opt::OptTable {
public:
  TAPIOptTable() : opt::OptTable(optionTables()) {
    setGroupedShortOptions(true);
  }
};

struct StubOptions {
  bool DeleteInput = false;
  bool DeletePrivate = false;
  bool TraceLibs = false;
};

struct CompareOptions {
  ArchitectureSet ArchsToIgnore;
};

struct Context {
  std::vector<std::string> Inputs;
  StubOptions StubOpt;
  CompareOptions CmpOpt;
  std::unique_ptr<llvm::raw_fd_stream> OutStream;
  FileType WriteFT = FileType::TBD_V5;
  bool Compact = false;
  Architecture Arch = AK_unknown;
};

// Use unique exit code to differentiate failures not directly caused from
// TextAPI operations. This is used for wrapping `compare` operations in
// automation and scripting.
const int NON_TAPI_EXIT_CODE = 2;
const std::string TOOLNAME = "llvm-readtapi";
ExitOnError ExitOnErr;
} // anonymous namespace

// Handle error reporting in cases where `ExitOnError` is not used.
static void reportError(Twine Message, int ExitCode = EXIT_FAILURE) {
  errs() << TOOLNAME << ": error: " << Message << "\n";
  errs().flush();
  exit(ExitCode);
}

// Handle warnings.
static void reportWarning(Twine Message) {
  errs() << TOOLNAME << ": warning: " << Message << "\n";
}

/// Get what the symlink points to.
/// This is a no-op on windows as it references POSIX level apis.
static void read_link(const Twine &Path, SmallVectorImpl<char> &Output) {
#if !defined(_MSC_VER) && !defined(__MINGW32__)
  Output.clear();
  if (Path.isTriviallyEmpty())
    return;

  SmallString<PATH_MAX> Storage;
  auto P = Path.toNullTerminatedStringRef(Storage);
  SmallString<PATH_MAX> Result;
  ssize_t Len;
  if ((Len = ::readlink(P.data(), Result.data(), PATH_MAX)) == -1)
    reportError("unable to read symlink: " + Path);
  Result.resize_for_overwrite(Len);
  Output.swap(Result);
#else
  reportError("unable to read symlink on windows: " + Path);
#endif
}

static std::unique_ptr<InterfaceFile>
getInterfaceFile(const StringRef Filename, bool ResetBanner = true) {
  ExitOnErr.setBanner(TOOLNAME + ": error: '" + Filename.str() + "' ");
  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
      MemoryBuffer::getFile(Filename, /*IsText=*/true);
  if (BufferOrErr.getError())
    ExitOnErr(errorCodeToError(BufferOrErr.getError()));
  auto Buffer = std::move(*BufferOrErr);

  std::unique_ptr<InterfaceFile> IF;
  switch (identify_magic(Buffer->getBuffer())) {
  case file_magic::macho_dynamically_linked_shared_lib:
  case file_magic::macho_dynamically_linked_shared_lib_stub:
  case file_magic::macho_universal_binary:
    IF = ExitOnErr(DylibReader::get(Buffer->getMemBufferRef()));
    break;
  case file_magic::tapi_file:
    IF = ExitOnErr(TextAPIReader::get(Buffer->getMemBufferRef()));
    break;
  default:
    reportError(Filename + ": unsupported file type");
  }

  if (ResetBanner)
    ExitOnErr.setBanner(TOOLNAME + ": error: ");
  return IF;
}

static bool handleCompareAction(const Context &Ctx) {
  if (Ctx.Inputs.size() != 2)
    reportError("compare only supports two input files",
                /*ExitCode=*/NON_TAPI_EXIT_CODE);

  // Override default exit code.
  ExitOnErr = ExitOnError(TOOLNAME + ": error: ",
                          /*DefaultErrorExitCode=*/NON_TAPI_EXIT_CODE);
  auto LeftIF = getInterfaceFile(Ctx.Inputs.front());
  auto RightIF = getInterfaceFile(Ctx.Inputs.at(1));

  // Remove all architectures to ignore before running comparison.
  auto removeArchFromIF = [](auto &IF, const ArchitectureSet &ArchSet,
                             const Architecture ArchToRemove) {
    if (!ArchSet.has(ArchToRemove))
      return;
    if (ArchSet.count() == 1)
      return;
    auto OutIF = IF->remove(ArchToRemove);
    if (!OutIF)
      ExitOnErr(OutIF.takeError());
    IF = std::move(*OutIF);
  };

  if (!Ctx.CmpOpt.ArchsToIgnore.empty()) {
    const ArchitectureSet LeftArchs = LeftIF->getArchitectures();
    const ArchitectureSet RightArchs = RightIF->getArchitectures();
    for (const auto Arch : Ctx.CmpOpt.ArchsToIgnore) {
      removeArchFromIF(LeftIF, LeftArchs, Arch);
      removeArchFromIF(RightIF, RightArchs, Arch);
    }
  }

  raw_ostream &OS = Ctx.OutStream ? *Ctx.OutStream : outs();
  return DiffEngine(LeftIF.get(), RightIF.get()).compareFiles(OS);
}

static bool handleWriteAction(const Context &Ctx,
                              std::unique_ptr<InterfaceFile> Out = nullptr) {
  if (!Out) {
    if (Ctx.Inputs.size() != 1)
      reportError("write only supports one input file");
    Out = getInterfaceFile(Ctx.Inputs.front());
  }
  raw_ostream &OS = Ctx.OutStream ? *Ctx.OutStream : outs();
  ExitOnErr(TextAPIWriter::writeToStream(OS, *Out, Ctx.WriteFT, Ctx.Compact));
  return EXIT_SUCCESS;
}

static bool handleMergeAction(const Context &Ctx) {
  if (Ctx.Inputs.size() < 2)
    reportError("merge requires at least two input files");

  std::unique_ptr<InterfaceFile> Out;
  for (StringRef FileName : Ctx.Inputs) {
    auto IF = getInterfaceFile(FileName);
    // On the first iteration copy the input file and skip merge.
    if (!Out) {
      Out = std::move(IF);
      continue;
    }
    Out = ExitOnErr(Out->merge(IF.get()));
  }
  return handleWriteAction(Ctx, std::move(Out));
}

static void stubifyImpl(std::unique_ptr<InterfaceFile> IF, Context &Ctx) {
  // TODO: Add inlining and magic merge support.
  if (Ctx.OutStream == nullptr) {
    std::error_code EC;
    assert(!IF->getPath().empty() && "Unknown output location");
    SmallString<PATH_MAX> OutputLoc = IF->getPath();
    replace_extension(OutputLoc, ".tbd");
    Ctx.OutStream = std::make_unique<llvm::raw_fd_stream>(OutputLoc, EC);
    if (EC)
      reportError("opening file '" + OutputLoc + ": " + EC.message());
  }

  handleWriteAction(Ctx, std::move(IF));
  // Clear out output stream after file has been written incase more files are
  // stubifed.
  Ctx.OutStream = nullptr;
}

static void stubifyDirectory(const StringRef InputPath, Context &Ctx) {
  assert(InputPath.back() != '/' && "Unexpected / at end of input path.");
  StringMap<std::vector<SymLink>> SymLinks;
  StringMap<std::unique_ptr<InterfaceFile>> Dylibs;
  StringMap<std::string> OriginalNames;
  std::set<std::pair<std::string, bool>> LibsToDelete;

  std::error_code EC;
  for (sys::fs::recursive_directory_iterator IT(InputPath, EC), IE; IT != IE;
       IT.increment(EC)) {
    if (EC == std::errc::no_such_file_or_directory) {
      reportWarning(IT->path() + ": " + EC.message());
      continue;
    }
    if (EC)
      reportError(IT->path() + ": " + EC.message());

    // Skip header directories (include/Headers/PrivateHeaders).
    StringRef Path = IT->path();
    if (sys::fs::is_directory(Path)) {
      const StringRef Stem = sys::path::stem(Path);
      if ((Stem == "include") || (Stem == "Headers") ||
          (Stem == "PrivateHeaders") || (Stem == "Modules")) {
        IT.no_push();
        continue;
      }
    }

    // Skip module files too.
    if (Path.ends_with(".map") || Path.ends_with(".modulemap"))
      continue;

    // Check if the entry is a symlink. We don't follow symlinks but we record
    // their content.
    bool IsSymLink;
    if (auto EC = sys::fs::is_symlink_file(Path, IsSymLink))
      reportError(Path + ": " + EC.message());

    if (IsSymLink) {
      IT.no_push();

      bool ShouldSkip;
      auto SymLinkEC = shouldSkipSymLink(Path, ShouldSkip);

      // If symlink is broken, for some reason, we should continue
      // trying to repair it before quitting.
      if (!SymLinkEC && ShouldSkip)
        continue;

      if (Ctx.StubOpt.DeletePrivate &&
          isPrivateLibrary(Path.drop_front(InputPath.size()), true)) {
        LibsToDelete.emplace(Path, false);
        continue;
      }

      SmallString<PATH_MAX> SymPath;
      read_link(Path, SymPath);
      // Sometimes there are broken symlinks that are absolute paths, which are
      // invalid during build time, but would be correct during runtime. In the
      // case of an absolute path we should check first if the path exists with
      // the known locations as prefix.
      SmallString<PATH_MAX> LinkSrc = Path;
      SmallString<PATH_MAX> LinkTarget;
      if (sys::path::is_absolute(SymPath)) {
        LinkTarget = InputPath;
        sys::path::append(LinkTarget, SymPath);

        // TODO: Investigate supporting a file manager for file system accesses.
        if (sys::fs::exists(LinkTarget)) {
          // Convert the absolute path to an relative path.
          if (auto ec = MachO::make_relative(LinkSrc, LinkTarget, SymPath))
            reportError(LinkTarget + ": " + EC.message());
        } else if (!sys::fs::exists(SymPath)) {
          reportWarning("ignoring broken symlink: " + Path);
          continue;
        } else {
          LinkTarget = SymPath;
        }
      } else {
        LinkTarget = LinkSrc;
        sys::path::remove_filename(LinkTarget);
        sys::path::append(LinkTarget, SymPath);
      }

      // For Apple SDKs, the symlink src is guaranteed to be a canonical path
      // because we don't follow symlinks when scanning. The symlink target is
      // constructed from the symlink path and needs to be canonicalized.
      if (auto ec = sys::fs::real_path(Twine(LinkTarget), LinkTarget)) {
        reportWarning(LinkTarget + ": " + ec.message());
        continue;
      }

      SymLinks[LinkTarget.c_str()].emplace_back(LinkSrc.str(),
                                                std::string(SymPath.str()));

      continue;
    }

    bool IsDirectory = false;
    if (auto EC = sys::fs::is_directory(Path, IsDirectory))
      reportError(Path + ": " + EC.message());
    if (IsDirectory)
      continue;

    if (Ctx.StubOpt.DeletePrivate &&
        isPrivateLibrary(Path.drop_front(InputPath.size()))) {
      IT.no_push();
      LibsToDelete.emplace(Path, false);
      continue;
    }
    auto IF = getInterfaceFile(Path);
    if (Ctx.StubOpt.TraceLibs)
      errs() << Path << "\n";

    // Normalize path for map lookup by removing the extension.
    SmallString<PATH_MAX> NormalizedPath(Path);
    replace_extension(NormalizedPath, "");

    auto [It, Inserted] = Dylibs.try_emplace(NormalizedPath.str());

    if ((IF->getFileType() == FileType::MachO_DynamicLibrary) ||
        (IF->getFileType() == FileType::MachO_DynamicLibrary_Stub)) {
      OriginalNames[NormalizedPath.c_str()] = IF->getPath();

      // Don't add this MachO dynamic library because we already have a
      // text-based stub recorded for this path.
      if (!Inserted)
        continue;
    }

    It->second = std::move(IF);
  }

  for (auto &Lib : Dylibs) {
    auto &Dylib = Lib.second;
    // Get the original file name.
    SmallString<PATH_MAX> NormalizedPath(Dylib->getPath());
    stubifyImpl(std::move(Dylib), Ctx);

    replace_extension(NormalizedPath, "");
    auto Found = OriginalNames.find(NormalizedPath.c_str());
    if (Found == OriginalNames.end())
      continue;

    if (Ctx.StubOpt.DeleteInput)
      LibsToDelete.emplace(Found->second, true);

    // Don't allow for more than 20 levels of symlinks when searching for
    // libraries to stubify.
    StringRef LibToCheck = Found->second;
    for (int i = 0; i < 20; ++i) {
      auto LinkIt = SymLinks.find(LibToCheck);
      if (LinkIt != SymLinks.end()) {
        for (auto &SymInfo : LinkIt->second) {
          SmallString<PATH_MAX> LinkSrc(SymInfo.SrcPath);
          SmallString<PATH_MAX> LinkTarget(SymInfo.LinkContent);
          replace_extension(LinkSrc, "tbd");
          replace_extension(LinkTarget, "tbd");

          if (auto EC = sys::fs::remove(LinkSrc))
            reportError(LinkSrc + " : " + EC.message());

          if (auto EC = sys::fs::create_link(LinkTarget, LinkSrc))
            reportError(LinkTarget + " : " + EC.message());

          if (Ctx.StubOpt.DeleteInput)
            LibsToDelete.emplace(SymInfo.SrcPath, true);

          LibToCheck = SymInfo.SrcPath;
        }
      } else
        break;
    }
  }

  // Recursively delete the directories. This will abort when they are not empty
  // or we reach the root of the SDK.
  for (const auto &[LibPath, IsInput] : LibsToDelete) {
    if (!IsInput && SymLinks.count(LibPath))
      continue;

    if (auto EC = sys::fs::remove(LibPath))
      reportError(LibPath + " : " + EC.message());

    std::error_code EC;
    auto Dir = sys::path::parent_path(LibPath);
    do {
      EC = sys::fs::remove(Dir);
      Dir = sys::path::parent_path(Dir);
      if (!Dir.starts_with(InputPath))
        break;
    } while (!EC);
  }
}

static bool handleStubifyAction(Context &Ctx) {
  if (Ctx.Inputs.empty())
    reportError("stubify requires at least one input file");

  if ((Ctx.Inputs.size() > 1) && (Ctx.OutStream != nullptr))
    reportError("cannot write multiple inputs into single output file");

  for (StringRef PathName : Ctx.Inputs) {
    bool IsDirectory = false;
    if (auto EC = sys::fs::is_directory(PathName, IsDirectory))
      reportError(PathName + ": " + EC.message());

    if (IsDirectory) {
      if (Ctx.OutStream != nullptr)
        reportError("cannot stubify directory'" + PathName +
                    "' into single output file");
      stubifyDirectory(PathName, Ctx);
      continue;
    }

    stubifyImpl(getInterfaceFile(PathName), Ctx);
    if (Ctx.StubOpt.DeleteInput)
      if (auto ec = sys::fs::remove(PathName))
        reportError("deleting file '" + PathName + ": " + ec.message());
  }
  return EXIT_SUCCESS;
}

using IFOperation =
    std::function<llvm::Expected<std::unique_ptr<InterfaceFile>>(
        const llvm::MachO::InterfaceFile &, Architecture)>;
static bool handleSingleFileAction(const Context &Ctx, const StringRef Action,
                                   IFOperation act) {
  if (Ctx.Inputs.size() != 1)
    reportError(Action + " only supports one input file");
  if (Ctx.Arch == AK_unknown)
    reportError(Action + " requires -arch <arch>");

  auto IF = getInterfaceFile(Ctx.Inputs.front(), /*ResetBanner=*/false);
  auto OutIF = act(*IF, Ctx.Arch);
  if (!OutIF)
    ExitOnErr(OutIF.takeError());

  return handleWriteAction(Ctx, std::move(*OutIF));
}

static void setStubOptions(opt::InputArgList &Args, StubOptions &Opt) {
  Opt.DeleteInput = Args.hasArg(OPT_delete_input);
  Opt.DeletePrivate = Args.hasArg(OPT_delete_private_libraries);
  Opt.TraceLibs = Args.hasArg(OPT_t);
}

int llvm_readtapi_main(int Argc, char **Argv, const llvm::ToolContext &) {
  BumpPtrAllocator A;
  StringSaver Saver(A);
  TAPIOptTable Tbl;
  Context Ctx;
  ExitOnErr.setBanner(TOOLNAME + ": error:");
  opt::InputArgList Args = Tbl.parseArgs(
      Argc, Argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) { reportError(Msg); });
  if (Args.hasArg(OPT_help)) {
    Tbl.printHelp(outs(),
                  "USAGE: llvm-readtapi <command> [-arch <architecture> "
                  "<options>]* <inputs> [-o "
                  "<output>]*",
                  "LLVM TAPI file reader and transformer");
    return EXIT_SUCCESS;
  }

  if (Args.hasArg(OPT_version)) {
    cl::PrintVersionMessage();
    return EXIT_SUCCESS;
  }

  for (opt::Arg *A : Args.filtered(OPT_INPUT))
    Ctx.Inputs.push_back(A->getValue());

  if (opt::Arg *A = Args.getLastArg(OPT_output_EQ)) {
    std::string OutputLoc = std::move(A->getValue());
    std::error_code EC;
    Ctx.OutStream = std::make_unique<llvm::raw_fd_stream>(OutputLoc, EC);
    if (EC)
      reportError("error opening the file '" + OutputLoc + EC.message(),
                  NON_TAPI_EXIT_CODE);
  }

  Ctx.Compact = Args.hasArg(OPT_compact);

  if (opt::Arg *A = Args.getLastArg(OPT_filetype_EQ)) {
    StringRef FT = A->getValue();
    Ctx.WriteFT = TextAPIWriter::parseFileType(FT);
    if (Ctx.WriteFT < FileType::TBD_V3)
      reportError("deprecated filetype '" + FT + "' is not supported to write");
    if (Ctx.WriteFT == FileType::Invalid)
      reportError("unsupported filetype '" + FT + "'");
  }

  auto SanitizeArch = [&](opt::Arg *A) {
    StringRef ArchStr = A->getValue();
    auto Arch = getArchitectureFromName(ArchStr);
    if (Arch == AK_unknown)
      reportError("unsupported architecture '" + ArchStr);
    return Arch;
  };

  if (opt::Arg *A = Args.getLastArg(OPT_arch_EQ))
    Ctx.Arch = SanitizeArch(A);

  for (opt::Arg *A : Args.filtered(OPT_ignore_arch_EQ))
    Ctx.CmpOpt.ArchsToIgnore.set(SanitizeArch(A));

  // Handle top level and exclusive operation.
  SmallVector<opt::Arg *, 1> ActionArgs(Args.filtered(OPT_action_group));

  if (ActionArgs.empty())
    // If no action specified, write out tapi file in requested format.
    return handleWriteAction(Ctx);

  if (ActionArgs.size() > 1) {
    std::string Buf;
    raw_string_ostream OS(Buf);
    OS << "only one of the following actions can be specified:";
    for (auto *Arg : ActionArgs)
      OS << " " << Arg->getSpelling();
    reportError(OS.str());
  }

  switch (ActionArgs.front()->getOption().getID()) {
  case OPT_compare:
    return handleCompareAction(Ctx);
  case OPT_merge:
    return handleMergeAction(Ctx);
  case OPT_extract:
    return handleSingleFileAction(Ctx, "extract", &InterfaceFile::extract);
  case OPT_remove:
    return handleSingleFileAction(Ctx, "remove", &InterfaceFile::remove);
  case OPT_stubify:
    setStubOptions(Args, Ctx.StubOpt);
    return handleStubifyAction(Ctx);
  }

  return EXIT_SUCCESS;
}
