//===-- 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/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.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_STR_TABLE_CODE
#include "TapiOpts.inc"
#undef OPTTABLE_STR_TABLE_CODE

#define OPTTABLE_PREFIXES_TABLE_CODE
#include "TapiOpts.inc"
#undef OPTTABLE_PREFIXES_TABLE_CODE

static constexpr opt::OptTable::Info InfoTable[] = {
#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__),
#include "TapiOpts.inc"
#undef OPTION
};

class TAPIOptTable : public opt::GenericOptTable {
public:
  TAPIOptTable()
      : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {
    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 main(int Argc, char **Argv) {
  InitLLVM X(Argc, Argv);
  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;
}
