//===- subzero/src/IceCompileServer.cpp - Compile server ------------------===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the basic commandline-based compile server.
///
//===----------------------------------------------------------------------===//

#include "IceCompileServer.h"

#include "IceClFlags.h"
#include "IceClFlagsExtra.h"
#include "IceELFStreamer.h"
#include "IceGlobalContext.h"

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#include "llvm/Bitcode/NaCl/NaClBitcodeMungeUtils.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/StreamingMemoryObject.h"
#pragma clang diagnostic pop

#include <fstream>
#include <iostream>
#include <thread>

namespace Ice {

namespace {

// Define a SmallVector backed buffer as a data stream, so that it
// can hold the generated binary version of the textual bitcode in the
// input file.
class TextDataStreamer : public llvm::DataStreamer {
public:
  TextDataStreamer() = default;
  ~TextDataStreamer() final = default;
  static TextDataStreamer *create(const IceString &Filename, std::string *Err);
  size_t GetBytes(unsigned char *Buf, size_t Len) final;

private:
  llvm::SmallVector<char, 1024> BitcodeBuffer;
  size_t Cursor = 0;
};

TextDataStreamer *TextDataStreamer::create(const IceString &Filename,
                                           std::string *Err) {
  TextDataStreamer *Streamer = new TextDataStreamer();
  llvm::raw_string_ostream ErrStrm(*Err);
  if (std::error_code EC = llvm::readNaClRecordTextAndBuildBitcode(
          Filename, Streamer->BitcodeBuffer, &ErrStrm)) {
    ErrStrm << EC.message();
    ErrStrm.flush();
    delete Streamer;
    return nullptr;
  }
  ErrStrm.flush();
  return Streamer;
}

size_t TextDataStreamer::GetBytes(unsigned char *Buf, size_t Len) {
  if (Cursor >= BitcodeBuffer.size())
    return 0;
  size_t Remaining = BitcodeBuffer.size();
  Len = std::min(Len, Remaining);
  for (size_t i = 0; i < Len; ++i)
    Buf[i] = BitcodeBuffer[Cursor + i];
  Cursor += Len;
  return Len;
}

std::unique_ptr<Ostream> makeStream(const IceString &Filename,
                                    std::error_code &EC) {
  if (Filename == "-") {
    return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(std::cout));
  } else {
    return std::unique_ptr<Ostream>(
        new llvm::raw_fd_ostream(Filename, EC, llvm::sys::fs::F_None));
  }
}

ErrorCodes getReturnValue(const Ice::ClFlagsExtra &Flags, ErrorCodes Val) {
  if (Flags.getAlwaysExitSuccess())
    return EC_None;
  return Val;
}

} // end of anonymous namespace

void CLCompileServer::run() {
  if (BuildDefs::dump()) {
    llvm::sys::PrintStackTraceOnErrorSignal();
  }
  ClFlags::parseFlags(argc, argv);
  ClFlags Flags;
  ClFlagsExtra ExtraFlags;
  ClFlags::getParsedClFlags(Flags);
  ClFlags::getParsedClFlagsExtra(ExtraFlags);

  std::error_code EC;
  std::unique_ptr<Ostream> Ls = makeStream(ExtraFlags.getLogFilename(), EC);
  if (EC) {
    llvm::report_fatal_error("Unable to open log file");
  }
  Ls->SetUnbuffered();
  std::unique_ptr<Ostream> Os;
  std::unique_ptr<ELFStreamer> ELFStr;
  switch (Flags.getOutFileType()) {
  case FT_Elf: {
    if (ExtraFlags.getOutputFilename() == "-") {
      *Ls << "Error: writing binary ELF to stdout is unsupported\n";
      return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
    }
    std::unique_ptr<llvm::raw_fd_ostream> FdOs(new llvm::raw_fd_ostream(
        ExtraFlags.getOutputFilename(), EC, llvm::sys::fs::F_None));
    if (EC) {
      *Ls << "Failed to open output file: " << ExtraFlags.getOutputFilename()
          << ":\n" << EC.message() << "\n";
      return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
    }
    ELFStr.reset(new ELFStreamer(*FdOs.get()));
    Os.reset(FdOs.release());
    // NaCl sets st_blksize to 0, and LLVM uses that to pick the
    // default preferred buffer size. Set to something non-zero.
    Os->SetBufferSize(1 << 14);
  } break;
  case FT_Asm:
  case FT_Iasm: {
    Os = makeStream(ExtraFlags.getOutputFilename(), EC);
    if (EC) {
      *Ls << "Failed to open output file: " << ExtraFlags.getOutputFilename()
          << ":\n" << EC.message() << "\n";
      return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
    }
    Os->SetUnbuffered();
  } break;
  }

  if (BuildDefs::minimal() && ExtraFlags.getBitcodeAsText())
    llvm::report_fatal_error("Can't specify 'bitcode-as-text' flag in "
                             "minimal build");

  IceString StrError;
  std::unique_ptr<llvm::DataStreamer> InputStream(
      (!BuildDefs::minimal() && ExtraFlags.getBitcodeAsText())
          ? TextDataStreamer::create(ExtraFlags.getIRFilename(), &StrError)
          : llvm::getDataFileStreamer(ExtraFlags.getIRFilename(), &StrError));
  if (!StrError.empty() || !InputStream) {
    llvm::SMDiagnostic Err(ExtraFlags.getIRFilename(),
                           llvm::SourceMgr::DK_Error, StrError);
    Err.print(ExtraFlags.getAppName().c_str(), *Ls);
    return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Bitcode));
  }

  Ctx.reset(
      new GlobalContext(Ls.get(), Os.get(), Ls.get(), ELFStr.get(), Flags));
  if (Ctx->getFlags().getNumTranslationThreads() != 0) {
    std::thread CompileThread([this, &ExtraFlags, &InputStream]() {
      Ctx->initParserThread();
      getCompiler().run(ExtraFlags, *Ctx.get(), std::move(InputStream));
    });
    CompileThread.join();
  } else {
    getCompiler().run(ExtraFlags, *Ctx.get(), std::move(InputStream));
  }
  transferErrorCode(getReturnValue(
      ExtraFlags, static_cast<ErrorCodes>(Ctx->getErrorStatus()->value())));
}

} // end of namespace Ice
