//===--- lldb-moduleimport-test.cpp - LLDB moduleimport tester ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This program simulates LLDB importing modules from the __apple_ast
// section in Mach-O files. We use it to test for regressions in the
// deserialization API.
//
//===----------------------------------------------------------------------===//

#include "swift/ASTSectionImporter/ASTSectionImporter.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/Validation.h"
#include "swift/Basic/Dwarf.h"
#include "llvm/Object/ELFObjectFile.h"
#include "swift/Basic/LLVMInitialize.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ManagedStatic.h"
#include <fstream>
#include <sstream>

void anchorForGetMainExecutable() {}

using namespace llvm::MachO;

static void printValidationInfo(llvm::StringRef data) {
  swift::serialization::ExtendedValidationInfo extendedInfo;
  swift::serialization::ValidationInfo info =
      swift::serialization::validateSerializedAST(data, &extendedInfo);
  if (info.status != swift::serialization::Status::Valid)
    return;

  if (!info.shortVersion.empty())
    llvm::outs() << "- Swift Version: " << info.shortVersion << "\n";
  llvm::outs() << "- Target: " << info.targetTriple << "\n";
  if (!extendedInfo.getSDKPath().empty())
    llvm::outs() << "- SDK path: " << extendedInfo.getSDKPath() << "\n";
  if (!extendedInfo.getExtraClangImporterOptions().empty()) {
    llvm::outs() << "- -Xcc options:";
    for (llvm::StringRef option : extendedInfo.getExtraClangImporterOptions())
      llvm::outs() << " " << option;
    llvm::outs() << "\n";
  }
}

int main(int argc, char **argv) {
  INITIALIZE_LLVM(argc, argv);

  // Command line handling.
  llvm::cl::list<std::string> InputNames(
    llvm::cl::Positional, llvm::cl::desc("compiled_swift_file1.o ..."),
    llvm::cl::OneOrMore);

  llvm::cl::opt<std::string> SDK(
    "sdk", llvm::cl::desc("path to the SDK to build against"));

  llvm::cl::opt<bool> DumpModule(
    "dump-module", llvm::cl::desc(
      "Dump the imported module after checking it imports just fine"));

  llvm::cl::opt<std::string> ModuleCachePath(
    "module-cache-path", llvm::cl::desc("Clang module cache path"));

  llvm::cl::list<std::string> ImportPaths(
    "I", llvm::cl::desc("add a directory to the import search path"));

  llvm::cl::list<std::string> FrameworkPaths(
    "F", llvm::cl::desc("add a directory to the framework search path"));

  llvm::cl::ParseCommandLineOptions(argc, argv);
  // Unregister our options so they don't interfere with the command line
  // parsing in CodeGen/BackendUtil.cpp.
  FrameworkPaths.removeArgument();
  ImportPaths.removeArgument();
  ModuleCachePath.removeArgument();
  DumpModule.removeArgument();
  SDK.removeArgument();
  InputNames.removeArgument();

  // If no SDK was specified via -sdk, check environment variable SDKROOT.
  if (SDK.getNumOccurrences() == 0) {
    const char *SDKROOT = getenv("SDKROOT");
    if (SDKROOT)
      SDK = SDKROOT;
  }

  // Create a Swift compiler.
  llvm::SmallVector<std::string, 4> modules;
  swift::CompilerInstance CI;
  swift::CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(
      llvm::sys::fs::getMainExecutable(argv[0],
          reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  Invocation.setSDKPath(SDK);
  Invocation.setTargetTriple(llvm::sys::getDefaultTargetTriple());
  Invocation.setModuleName("lldbtest");
  Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath;
  Invocation.setImportSearchPaths(ImportPaths);
  std::vector<swift::SearchPathOptions::FrameworkSearchPath> FramePaths;
  for (const auto &path : FrameworkPaths) {
    FramePaths.push_back({path, /*isSystem=*/false});
  }
  Invocation.setFrameworkSearchPaths(FramePaths);

  if (CI.setup(Invocation))
    return 1;

  std::vector<llvm::object::OwningBinary<llvm::object::ObjectFile>> ObjFiles;

  // Fetch the serialized module bitstreams from the Mach-O files and
  // register them with the module loader.
  for (std::string name : InputNames) {
    auto OF = llvm::object::ObjectFile::createObjectFile(name);
    if (!OF) {
      llvm::outs() << name << " is not an object file.\n";
      exit(1);
    }
    auto *Obj = OF->getBinary();
    auto *MachO = llvm::dyn_cast<llvm::object::MachOObjectFile>(Obj);
    auto *ELF   = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Obj);
    if (MachO) {
      for (auto &Symbol : Obj->symbols()) {
        auto RawSym = Symbol.getRawDataRefImpl();
        llvm::MachO::nlist nlist = MachO->getSymbolTableEntry(RawSym);
        if (nlist.n_type == N_AST) {
          auto Path = MachO->getSymbolName(RawSym);
          if (!Path) {
            llvm::outs() << "Cannot get symbol name\n;";
            exit(1);
          }

          auto fileBuf = llvm::MemoryBuffer::getFile(*Path);
          if (!fileBuf) {
            llvm::outs() << "Cannot read from '" << *Path
                         << "': " << fileBuf.getError().message();
            exit(1);
          }

          if (!parseASTSection(CI.getSerializedModuleLoader(),
                               fileBuf.get()->getBuffer(), modules)) {
            exit(1);
          }

          for (auto path : modules)
            llvm::outs() << "Loaded module " << path << " from " << name
                         << "\n";
          printValidationInfo(fileBuf.get()->getBuffer());

          // Deliberately leak the llvm::MemoryBuffer. We can't delete it
          // while it's in use anyway.
          fileBuf.get().release();
        }
      }
    }
    for (auto &Section : Obj->sections()) {
      llvm::StringRef Name;
      Section.getName(Name);
      if ((MachO && Name == swift::MachOASTSectionName) ||
          (ELF   && Name == swift::ELFASTSectionName)) {
        llvm::StringRef Buf;
        Section.getContents(Buf);
        if (!parseASTSection(CI.getSerializedModuleLoader(), Buf, modules))
          exit(1);

        for (auto path : modules)
          llvm::outs() << "Loaded module " << path << " from " << name
                       << "\n";
        printValidationInfo(Buf);
      }
    }
    ObjFiles.push_back(std::move(*OF));
  }

  // Attempt to import all modules we found.
  for (auto path : modules) {
    llvm::outs() << "Importing " << path << "... ";

#ifdef SWIFT_SUPPORTS_SUBMODULES
    std::vector<std::pair<swift::Identifier, swift::SourceLoc> > AccessPath;
    for (auto i = llvm::sys::path::begin(path);
         i != llvm::sys::path::end(path); ++i)
      if (!llvm::sys::path::is_separator((*i)[0]))
          AccessPath.push_back({ CI.getASTContext().getIdentifier(*i),
                                 swift::SourceLoc() });
#else
    std::vector<std::pair<swift::Identifier, swift::SourceLoc> > AccessPath;
    AccessPath.push_back({ CI.getASTContext().getIdentifier(path),
                           swift::SourceLoc() });
#endif

    auto Module = CI.getASTContext().getModule(AccessPath);
    if (!Module) {
      llvm::errs() << "FAIL!\n";
      return 1;
    }
    llvm::outs() << "ok!\n";
    if (DumpModule) {
      llvm::SmallVector<swift::Decl*, 10> Decls;
      Module->getTopLevelDecls(Decls);
      for (auto Decl : Decls) {
        Decl->dump(llvm::outs());
      }
    }
  }
  return 0;
}
