//===-- 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 PREFIX(NAME, VALUE)                                                    \
  static constexpr StringLiteral NAME##_init[] = VALUE;                        \
  static constexpr ArrayRef<StringLiteral> NAME(NAME##_init,                   \
                                                std::size(NAME##_init) - 1);
#include "TapiOpts.inc"
#undef PREFIX

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(InfoTable) {
    setGroupedShortOptions(true);
  }
};

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

struct Context {
  std::vector<std::string> Inputs;
  StubOptions StubOpt;
  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);
  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:
    LLVM_FALLTHROUGH;
  case file_magic::macho_dynamically_linked_shared_lib_stub:
    LLVM_FALLTHROUGH;
  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));

  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) and module
    // files.
    StringRef Path = IT->path();
    if (Path.ends_with("/include") || Path.ends_with("/Headers") ||
        Path.ends_with("/PrivateHeaders") || Path.ends_with("/Modules") ||
        Path.ends_with(".map") || Path.ends_with(".modulemap")) {
      IT.no_push();
      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;
      }

      auto itr = SymLinks.insert({LinkTarget.c_str(), std::vector<SymLink>()});
      itr.first->second.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, "");

    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 (Dylibs.count(NormalizedPath.c_str()))
        continue;
    }

    Dylibs[NormalizedPath.c_str()] = 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.str());
      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 + "'");
  }

  if (opt::Arg *A = Args.getLastArg(OPT_arch_EQ)) {
    StringRef Arch = A->getValue();
    Ctx.Arch = getArchitectureFromName(Arch);
    if (Ctx.Arch == AK_unknown)
      reportError("unsupported architecture '" + Arch);
  }
  // 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;
}
