//===- OffloadBundle.cpp - Utilities for offload bundles---*- 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
//
//===----------------------------------------------------------------===//

#include "llvm/Object/OffloadBundle.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/Timer.h"

using namespace llvm;
using namespace llvm::object;

static TimerGroup OffloadBundlerTimerGroup("Offload Bundler Timer Group",
                                           "Timer group for offload bundler");

// Extract an Offload bundle (usually a Offload Bundle) from a fat_bin
// section.
Error extractOffloadBundle(MemoryBufferRef Contents, uint64_t SectionOffset,
                           StringRef FileName,
                           SmallVectorImpl<OffloadBundleFatBin> &Bundles) {

  size_t Offset = 0;
  size_t NextbundleStart = 0;
  StringRef Magic;
  std::unique_ptr<MemoryBuffer> Buffer;

  // There could be multiple offloading bundles stored at this section.
  while ((NextbundleStart != StringRef::npos) &&
         (Offset < Contents.getBuffer().size())) {
    Buffer =
        MemoryBuffer::getMemBuffer(Contents.getBuffer().drop_front(Offset), "",
                                   /*RequiresNullTerminator=*/false);

    if (identify_magic((*Buffer).getBuffer()) ==
        file_magic::offload_bundle_compressed) {
      Magic = "CCOB";
      // Decompress this bundle first.
      NextbundleStart = (*Buffer).getBuffer().find(Magic, Magic.size());
      if (NextbundleStart == StringRef::npos)
        NextbundleStart = (*Buffer).getBuffer().size();

      ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr =
          MemoryBuffer::getMemBuffer(
              (*Buffer).getBuffer().take_front(NextbundleStart), FileName,
              false);
      if (std::error_code EC = CodeOrErr.getError())
        return createFileError(FileName, EC);

      Expected<std::unique_ptr<MemoryBuffer>> DecompressedBufferOrErr =
          CompressedOffloadBundle::decompress(**CodeOrErr, nullptr);
      if (!DecompressedBufferOrErr)
        return createStringError("failed to decompress input: " +
                                 toString(DecompressedBufferOrErr.takeError()));

      auto FatBundleOrErr = OffloadBundleFatBin::create(
          **DecompressedBufferOrErr, Offset, FileName, true);
      if (!FatBundleOrErr)
        return FatBundleOrErr.takeError();

      // Add current Bundle to list.
      Bundles.emplace_back(std::move(**FatBundleOrErr));

    } else if (identify_magic((*Buffer).getBuffer()) ==
               file_magic::offload_bundle) {
      // Create the OffloadBundleFatBin object. This will also create the Bundle
      // Entry list info.
      auto FatBundleOrErr = OffloadBundleFatBin::create(
          *Buffer, SectionOffset + Offset, FileName);
      if (!FatBundleOrErr)
        return FatBundleOrErr.takeError();

      // Add current Bundle to list.
      Bundles.emplace_back(std::move(**FatBundleOrErr));

      Magic = "__CLANG_OFFLOAD_BUNDLE__";
      NextbundleStart = (*Buffer).getBuffer().find(Magic, Magic.size());
    }

    if (NextbundleStart != StringRef::npos)
      Offset += NextbundleStart;
  }

  return Error::success();
}

Error OffloadBundleFatBin::readEntries(StringRef Buffer,
                                       uint64_t SectionOffset) {
  uint64_t NumOfEntries = 0;

  BinaryStreamReader Reader(Buffer, llvm::endianness::little);

  // Read the Magic String first.
  StringRef Magic;
  if (auto EC = Reader.readFixedString(Magic, 24))
    return errorCodeToError(object_error::parse_failed);

  // Read the number of Code Objects (Entries) in the current Bundle.
  if (auto EC = Reader.readInteger(NumOfEntries))
    return errorCodeToError(object_error::parse_failed);

  NumberOfEntries = NumOfEntries;

  // For each Bundle Entry (code object).
  for (uint64_t I = 0; I < NumOfEntries; I++) {
    uint64_t EntrySize;
    uint64_t EntryOffset;
    uint64_t EntryIDSize;
    StringRef EntryID;

    if (Error Err = Reader.readInteger(EntryOffset))
      return Err;

    if (Error Err = Reader.readInteger(EntrySize))
      return Err;

    if (Error Err = Reader.readInteger(EntryIDSize))
      return Err;

    if (Error Err = Reader.readFixedString(EntryID, EntryIDSize))
      return Err;

    auto Entry = std::make_unique<OffloadBundleEntry>(
        EntryOffset + SectionOffset, EntrySize, EntryIDSize, EntryID);

    Entries.push_back(*Entry);
  }

  return Error::success();
}

Expected<std::unique_ptr<OffloadBundleFatBin>>
OffloadBundleFatBin::create(MemoryBufferRef Buf, uint64_t SectionOffset,
                            StringRef FileName, bool Decompress) {
  if (Buf.getBufferSize() < 24)
    return errorCodeToError(object_error::parse_failed);

  // Check for magic bytes.
  if ((identify_magic(Buf.getBuffer()) != file_magic::offload_bundle) &&
      (identify_magic(Buf.getBuffer()) !=
       file_magic::offload_bundle_compressed))
    return errorCodeToError(object_error::parse_failed);

  std::unique_ptr<OffloadBundleFatBin> TheBundle(
      new OffloadBundleFatBin(Buf, FileName, Decompress));

  // Read the Bundle Entries.
  Error Err =
      TheBundle->readEntries(Buf.getBuffer(), Decompress ? 0 : SectionOffset);
  if (Err)
    return Err;

  return std::move(TheBundle);
}

Error OffloadBundleFatBin::extractBundle(const ObjectFile &Source) {
  // This will extract all entries in the Bundle.
  for (OffloadBundleEntry &Entry : Entries) {

    if (Entry.Size == 0)
      continue;

    // create output file name. Which should be
    // <fileName>-offset<Offset>-size<Size>.co"
    std::string Str = getFileName().str() + "-offset" + itostr(Entry.Offset) +
                      "-size" + itostr(Entry.Size) + ".co";
    if (Error Err = object::extractCodeObject(Source, Entry.Offset, Entry.Size,
                                              StringRef(Str)))
      return Err;
  }

  return Error::success();
}

Error object::extractOffloadBundleFatBinary(
    const ObjectFile &Obj, SmallVectorImpl<OffloadBundleFatBin> &Bundles) {
  // Ignore unsupported object formats.
  if (!Obj.isELF() && !Obj.isCOFF())
    return Error::success();

  // Iterate through Sections until we find an offload_bundle section.
  for (SectionRef Sec : Obj.sections()) {
    Expected<StringRef> Buffer = Sec.getContents();
    if (!Buffer)
      return Buffer.takeError();

    // If it does not start with the reserved suffix, just skip this section.
    if ((llvm::identify_magic(*Buffer) == file_magic::offload_bundle) ||
        (llvm::identify_magic(*Buffer) ==
         file_magic::offload_bundle_compressed)) {

      uint64_t SectionOffset = 0;
      if (Obj.isELF()) {
        SectionOffset = ELFSectionRef(Sec).getOffset();
      } else if (Obj.isCOFF()) {
        const COFFObjectFile &COFF = cast<COFFObjectFile>(Obj);
        Expected<const coff_section *> SecOrErr =
            COFF.getSection(COFF.getSectionID(Sec));
        if (!SecOrErr)
          return SecOrErr.takeError();
        SectionOffset = (*SecOrErr)->PointerToRawData;
      }

      MemoryBufferRef Contents(*Buffer, Obj.getFileName());
      if (Error Err = extractOffloadBundle(Contents, SectionOffset,
                                           Obj.getFileName(), Bundles))
        return Err;
    }
  }
  return Error::success();
}

Error object::extractCodeObject(const ObjectFile &Source, size_t Offset,
                                size_t Size, StringRef OutputFileName) {
  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
      FileOutputBuffer::create(OutputFileName, Size);

  if (!BufferOrErr)
    return BufferOrErr.takeError();

  Expected<MemoryBufferRef> InputBuffOrErr = Source.getMemoryBufferRef();
  if (Error Err = InputBuffOrErr.takeError())
    return createFileError(Source.getFileName(), std::move(Err));

  if (Size > InputBuffOrErr->getBufferSize())
    return createStringError("size in URI (%zu) is larger than source (%zu)",
                             Size, InputBuffOrErr->getBufferSize());

  if (Offset > InputBuffOrErr->getBufferSize())
    return createStringError(
        "offset in URI (%zu) is beyond the end of the source (%zu)", Offset,
        InputBuffOrErr->getBufferSize());

  if (Offset + Size > InputBuffOrErr->getBufferSize())
    return createStringError(
        "offset + size (%zu) in URI is beyond the end of the source (%zu)",
        Offset + Size, InputBuffOrErr->getBufferSize());

  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
  std::copy(InputBuffOrErr->getBufferStart() + Offset,
            InputBuffOrErr->getBufferStart() + Offset + Size,
            Buf->getBufferStart());
  if (Error E = Buf->commit())
    return createFileError(OutputFileName, std::move(E));

  return Error::success();
}

Error object::extractCodeObject(const MemoryBufferRef Buffer, int64_t Offset,
                                int64_t Size, StringRef OutputFileName) {
  Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
      FileOutputBuffer::create(OutputFileName, Size);
  if (!BufferOrErr)
    return BufferOrErr.takeError();

  std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr);
  std::copy(Buffer.getBufferStart() + Offset,
            Buffer.getBufferStart() + Offset + Size, Buf->getBufferStart());

  return Buf->commit();
}

// given a file name, offset, and size, extract data into a code object file,
// into file "<SourceFile>-offset<Offset>-size<Size>.co".
Error object::extractOffloadBundleByURI(StringRef URIstr) {
  // create a URI object
  Expected<std::unique_ptr<OffloadBundleURI>> UriOrErr(
      OffloadBundleURI::createOffloadBundleURI(URIstr, FILE_URI));

  if (!UriOrErr)
    return UriOrErr.takeError();

  OffloadBundleURI &Uri = **UriOrErr;
  std::string OutputFile = Uri.FileName.str();
  OutputFile +=
      "-offset" + itostr(Uri.Offset) + "-size" + itostr(Uri.Size) + ".co";

  // Create an ObjectFile object from uri.file_uri.
  auto ObjOrErr = ObjectFile::createObjectFile(Uri.FileName);
  if (!ObjOrErr)
    return ObjOrErr.takeError();

  auto Obj = ObjOrErr->getBinary();
  if (Error Err =
          object::extractCodeObject(*Obj, Uri.Offset, Uri.Size, OutputFile))
    return createFileError(Uri.FileName, std::move(Err));

  return Error::success();
}

// Utility function to format numbers with commas.
static std::string formatWithCommas(unsigned long long Value) {
  std::string Num = std::to_string(Value);
  int InsertPosition = Num.length() - 3;
  while (InsertPosition > 0) {
    Num.insert(InsertPosition, ",");
    InsertPosition -= 3;
  }
  return Num;
}

Expected<std::unique_ptr<MemoryBuffer>>
CompressedOffloadBundle::compress(compression::Params P,
                                  const MemoryBuffer &Input, uint16_t Version,
                                  raw_ostream *VerboseStream) {
  if (!compression::zstd::isAvailable() && !compression::zlib::isAvailable())
    return createStringError("compression not supported.");
  Timer HashTimer("Hash Calculation Timer", "Hash calculation time",
                  OffloadBundlerTimerGroup);
  if (VerboseStream)
    HashTimer.startTimer();
  MD5 Hash;
  MD5::MD5Result Result;
  Hash.update(Input.getBuffer());
  Hash.final(Result);
  uint64_t TruncatedHash = Result.low();
  if (VerboseStream)
    HashTimer.stopTimer();

  SmallVector<uint8_t, 0> CompressedBuffer;
  auto BufferUint8 = ArrayRef<uint8_t>(
      reinterpret_cast<const uint8_t *>(Input.getBuffer().data()),
      Input.getBuffer().size());
  Timer CompressTimer("Compression Timer", "Compression time",
                      OffloadBundlerTimerGroup);
  if (VerboseStream)
    CompressTimer.startTimer();
  compression::compress(P, BufferUint8, CompressedBuffer);
  if (VerboseStream)
    CompressTimer.stopTimer();

  uint16_t CompressionMethod = static_cast<uint16_t>(P.format);

  // Store sizes in 64-bit variables first.
  uint64_t UncompressedSize64 = Input.getBuffer().size();
  uint64_t TotalFileSize64;

  // Calculate total file size based on version.
  if (Version == 2) {
    // For V2, ensure the sizes don't exceed 32-bit limit.
    if (UncompressedSize64 > std::numeric_limits<uint32_t>::max())
      return createStringError("uncompressed size (%llu) exceeds version 2 "
                               "unsigned 32-bit integer limit",
                               UncompressedSize64);
    TotalFileSize64 = MagicNumber.size() + sizeof(uint32_t) + sizeof(Version) +
                      sizeof(CompressionMethod) + sizeof(uint32_t) +
                      sizeof(TruncatedHash) + CompressedBuffer.size();
    if (TotalFileSize64 > std::numeric_limits<uint32_t>::max())
      return createStringError("total file size (%llu) exceeds version 2 "
                               "unsigned 32-bit integer limit",
                               TotalFileSize64);

  } else { // Version 3.
    TotalFileSize64 = MagicNumber.size() + sizeof(uint64_t) + sizeof(Version) +
                      sizeof(CompressionMethod) + sizeof(uint64_t) +
                      sizeof(TruncatedHash) + CompressedBuffer.size();
  }

  SmallVector<char, 0> FinalBuffer;
  raw_svector_ostream OS(FinalBuffer);
  OS << MagicNumber;
  OS.write(reinterpret_cast<const char *>(&Version), sizeof(Version));
  OS.write(reinterpret_cast<const char *>(&CompressionMethod),
           sizeof(CompressionMethod));

  // Write size fields according to version.
  if (Version == 2) {
    uint32_t TotalFileSize32 = static_cast<uint32_t>(TotalFileSize64);
    uint32_t UncompressedSize32 = static_cast<uint32_t>(UncompressedSize64);
    OS.write(reinterpret_cast<const char *>(&TotalFileSize32),
             sizeof(TotalFileSize32));
    OS.write(reinterpret_cast<const char *>(&UncompressedSize32),
             sizeof(UncompressedSize32));
  } else { // Version 3.
    OS.write(reinterpret_cast<const char *>(&TotalFileSize64),
             sizeof(TotalFileSize64));
    OS.write(reinterpret_cast<const char *>(&UncompressedSize64),
             sizeof(UncompressedSize64));
  }

  OS.write(reinterpret_cast<const char *>(&TruncatedHash),
           sizeof(TruncatedHash));
  OS.write(reinterpret_cast<const char *>(CompressedBuffer.data()),
           CompressedBuffer.size());

  if (VerboseStream) {
    auto MethodUsed = P.format == compression::Format::Zstd ? "zstd" : "zlib";
    double CompressionRate =
        static_cast<double>(UncompressedSize64) / CompressedBuffer.size();
    double CompressionTimeSeconds = CompressTimer.getTotalTime().getWallTime();
    double CompressionSpeedMBs =
        (UncompressedSize64 / (1024.0 * 1024.0)) / CompressionTimeSeconds;
    *VerboseStream << "Compressed bundle format version: " << Version << "\n"
                   << "Total file size (including headers): "
                   << formatWithCommas(TotalFileSize64) << " bytes\n"
                   << "Compression method used: " << MethodUsed << "\n"
                   << "Compression level: " << P.level << "\n"
                   << "Binary size before compression: "
                   << formatWithCommas(UncompressedSize64) << " bytes\n"
                   << "Binary size after compression: "
                   << formatWithCommas(CompressedBuffer.size()) << " bytes\n"
                   << "Compression rate: " << format("%.2lf", CompressionRate)
                   << "\n"
                   << "Compression ratio: "
                   << format("%.2lf%%", 100.0 / CompressionRate) << "\n"
                   << "Compression speed: "
                   << format("%.2lf MB/s", CompressionSpeedMBs) << "\n"
                   << "Truncated MD5 hash: " << format_hex(TruncatedHash, 16)
                   << "\n";
  }

  return MemoryBuffer::getMemBufferCopy(
      StringRef(FinalBuffer.data(), FinalBuffer.size()));
}

// Use packed structs to avoid padding, such that the structs map the serialized
// format.
LLVM_PACKED_START
union RawCompressedBundleHeader {
  struct CommonFields {
    uint32_t Magic;
    uint16_t Version;
    uint16_t Method;
  };

  struct V1Header {
    CommonFields Common;
    uint32_t UncompressedFileSize;
    uint64_t Hash;
  };

  struct V2Header {
    CommonFields Common;
    uint32_t FileSize;
    uint32_t UncompressedFileSize;
    uint64_t Hash;
  };

  struct V3Header {
    CommonFields Common;
    uint64_t FileSize;
    uint64_t UncompressedFileSize;
    uint64_t Hash;
  };

  CommonFields Common;
  V1Header V1;
  V2Header V2;
  V3Header V3;
};
LLVM_PACKED_END

// Helper method to get header size based on version.
static size_t getHeaderSize(uint16_t Version) {
  switch (Version) {
  case 1:
    return sizeof(RawCompressedBundleHeader::V1Header);
  case 2:
    return sizeof(RawCompressedBundleHeader::V2Header);
  case 3:
    return sizeof(RawCompressedBundleHeader::V3Header);
  default:
    llvm_unreachable("Unsupported version");
  }
}

Expected<CompressedOffloadBundle::CompressedBundleHeader>
CompressedOffloadBundle::CompressedBundleHeader::tryParse(StringRef Blob) {
  assert(Blob.size() >= sizeof(RawCompressedBundleHeader::CommonFields));
  assert(identify_magic(Blob) == file_magic::offload_bundle_compressed);

  RawCompressedBundleHeader Header;
  std::memcpy(&Header, Blob.data(), std::min(Blob.size(), sizeof(Header)));

  CompressedBundleHeader Normalized;
  Normalized.Version = Header.Common.Version;

  size_t RequiredSize = getHeaderSize(Normalized.Version);

  if (Blob.size() < RequiredSize)
    return createStringError("compressed bundle header size too small");

  switch (Normalized.Version) {
  case 1:
    Normalized.UncompressedFileSize = Header.V1.UncompressedFileSize;
    Normalized.Hash = Header.V1.Hash;
    break;
  case 2:
    Normalized.FileSize = Header.V2.FileSize;
    Normalized.UncompressedFileSize = Header.V2.UncompressedFileSize;
    Normalized.Hash = Header.V2.Hash;
    break;
  case 3:
    Normalized.FileSize = Header.V3.FileSize;
    Normalized.UncompressedFileSize = Header.V3.UncompressedFileSize;
    Normalized.Hash = Header.V3.Hash;
    break;
  default:
    return createStringError("unknown compressed bundle version");
  }

  // Determine compression format.
  switch (Header.Common.Method) {
  case static_cast<uint16_t>(compression::Format::Zlib):
  case static_cast<uint16_t>(compression::Format::Zstd):
    Normalized.CompressionFormat =
        static_cast<compression::Format>(Header.Common.Method);
    break;
  default:
    return createStringError("unknown compressing method");
  }

  return Normalized;
}

Expected<std::unique_ptr<MemoryBuffer>>
CompressedOffloadBundle::decompress(const MemoryBuffer &Input,
                                    raw_ostream *VerboseStream) {
  StringRef Blob = Input.getBuffer();

  // Check minimum header size (using V1 as it's the smallest).
  if (Blob.size() < sizeof(RawCompressedBundleHeader::CommonFields))
    return MemoryBuffer::getMemBufferCopy(Blob);

  if (identify_magic(Blob) != file_magic::offload_bundle_compressed) {
    if (VerboseStream)
      *VerboseStream << "Uncompressed bundle\n";
    return MemoryBuffer::getMemBufferCopy(Blob);
  }

  Expected<CompressedBundleHeader> HeaderOrErr =
      CompressedBundleHeader::tryParse(Blob);
  if (!HeaderOrErr)
    return HeaderOrErr.takeError();

  const CompressedBundleHeader &Normalized = *HeaderOrErr;
  unsigned ThisVersion = Normalized.Version;
  size_t HeaderSize = getHeaderSize(ThisVersion);

  compression::Format CompressionFormat = Normalized.CompressionFormat;

  size_t TotalFileSize = Normalized.FileSize.value_or(0);
  size_t UncompressedSize = Normalized.UncompressedFileSize;
  auto StoredHash = Normalized.Hash;

  Timer DecompressTimer("Decompression Timer", "Decompression time",
                        OffloadBundlerTimerGroup);
  if (VerboseStream)
    DecompressTimer.startTimer();

  SmallVector<uint8_t, 0> DecompressedData;
  StringRef CompressedData =
      Blob.substr(HeaderSize, TotalFileSize - HeaderSize);

  if (Error DecompressionError = compression::decompress(
          CompressionFormat, arrayRefFromStringRef(CompressedData),
          DecompressedData, UncompressedSize))
    return createStringError("could not decompress embedded file contents: " +
                             toString(std::move(DecompressionError)));

  if (VerboseStream) {
    DecompressTimer.stopTimer();

    double DecompressionTimeSeconds =
        DecompressTimer.getTotalTime().getWallTime();

    // Recalculate MD5 hash for integrity check.
    Timer HashRecalcTimer("Hash Recalculation Timer", "Hash recalculation time",
                          OffloadBundlerTimerGroup);
    HashRecalcTimer.startTimer();
    MD5 Hash;
    MD5::MD5Result Result;
    Hash.update(ArrayRef<uint8_t>(DecompressedData));
    Hash.final(Result);
    uint64_t RecalculatedHash = Result.low();
    HashRecalcTimer.stopTimer();
    bool HashMatch = (StoredHash == RecalculatedHash);

    double CompressionRate =
        static_cast<double>(UncompressedSize) / CompressedData.size();
    double DecompressionSpeedMBs =
        (UncompressedSize / (1024.0 * 1024.0)) / DecompressionTimeSeconds;

    *VerboseStream << "Compressed bundle format version: " << ThisVersion
                   << "\n";
    if (ThisVersion >= 2)
      *VerboseStream << "Total file size (from header): "
                     << formatWithCommas(TotalFileSize) << " bytes\n";
    *VerboseStream
        << "Decompression method: "
        << (CompressionFormat == compression::Format::Zlib ? "zlib" : "zstd")
        << "\n"
        << "Size before decompression: "
        << formatWithCommas(CompressedData.size()) << " bytes\n"
        << "Size after decompression: " << formatWithCommas(UncompressedSize)
        << " bytes\n"
        << "Compression rate: " << format("%.2lf", CompressionRate) << "\n"
        << "Compression ratio: " << format("%.2lf%%", 100.0 / CompressionRate)
        << "\n"
        << "Decompression speed: "
        << format("%.2lf MB/s", DecompressionSpeedMBs) << "\n"
        << "Stored hash: " << format_hex(StoredHash, 16) << "\n"
        << "Recalculated hash: " << format_hex(RecalculatedHash, 16) << "\n"
        << "Hashes match: " << (HashMatch ? "Yes" : "No") << "\n";
  }

  return MemoryBuffer::getMemBufferCopy(toStringRef(DecompressedData));
}
