// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/cksum.h>
#include <lib/syslog/cpp/macros.h>
#include <string.h>
#include <zircon/compiler.h>

#include <fbl/array.h>
#include <src/lib/chunked-compression/chunked-archive.h>
#include <src/lib/chunked-compression/status.h>

namespace chunked_compression {

// SeekTable

size_t SeekTable::CompressedSize() const {
  size_t sz = SerializedHeaderSize();

  size_t biggest_offset = 0;
  for (const SeekTableEntry& entry : entries_) {
    if (entry.compressed_offset >= biggest_offset) {
      sz = entry.compressed_offset + entry.compressed_size;
      biggest_offset = entry.compressed_offset;
    }
  }

  return sz;
}

size_t SeekTable::SerializedHeaderSize() const {
  return kChunkArchiveSeekTableOffset + (entries_.size() * sizeof(SeekTableEntry));
}

size_t SeekTable::DecompressedSize() const {
  size_t sz = 0;

  size_t biggest_offset = 0;
  for (const SeekTableEntry& entry : entries_) {
    if (entry.decompressed_offset >= biggest_offset) {
      sz = entry.decompressed_offset + entry.decompressed_size;
      biggest_offset = entry.decompressed_offset;
    }
  }

  return sz;
}

std::optional<size_t> SeekTable::EntryForCompressedOffset(size_t offset) const {
  for (size_t i = 0; i < entries_.size(); ++i) {
    const SeekTableEntry& entry = entries_[i];
    if (entry.compressed_offset <= offset &&
        offset < entry.compressed_offset + entry.compressed_size) {
      return i;
    }
  }
  return std::nullopt;
}

std::optional<size_t> SeekTable::EntryForDecompressedOffset(size_t offset) const {
  for (size_t i = 0; i < entries_.size(); ++i) {
    const SeekTableEntry& entry = entries_[i];
    if (entry.decompressed_offset <= offset &&
        offset < entry.decompressed_offset + entry.decompressed_size) {
      return i;
    }
  }
  return std::nullopt;
}

// HeaderReader

Status HeaderReader::Parse(const void* void_data, size_t len, size_t file_length, SeekTable* out) {
  if (!void_data || !out) {
    return kStatusErrInvalidArgs;
  } else if (len < kChunkArchiveMinHeaderSize) {
    return kStatusErrBufferTooSmall;
  } else if (file_length < len) {
    return kStatusErrInvalidArgs;
  }
  const uint8_t* data = static_cast<const uint8_t*>(void_data);
  Status status;
  if ((status = CheckMagic(data, len)) != kStatusOk) {
    return status;
  } else if ((status = CheckVersion(data, len)) != kStatusOk) {
    return status;
  }
  ChunkCountType num_chunks;
  if ((status = GetNumChunks(data, len, &num_chunks)) != kStatusOk) {
    return status;
  } else if (num_chunks > kChunkArchiveMaxFrames) {
    // It's possible that the num_chunks field was corrupted. Treat this as an integrity error.
    return kStatusErrIoDataIntegrity;
  }
  size_t expected_header_length =
      kChunkArchiveSeekTableOffset + (num_chunks * sizeof(SeekTableEntry));
  if (expected_header_length > len) {
    // Note that we can't distinguish between two cases:
    // - The client passed a truncated buffer.
    // - The num_chunks field was corrupted.
    // The second case will be caught by the checksum, so assume that the former case applies here.
    return kStatusErrBufferTooSmall;
  }
  // IMPORTANT: New fields should be parsed after the checksum is verified.
  // (The magic and num_chunks fields are necessary to parse first, so they are exceptions.)
  if ((status = CheckChecksum(data, expected_header_length)) != kStatusOk) {
    return status;
  }
  fbl::Array<SeekTableEntry> table;
  if ((status = ParseSeekTable(data, len, file_length, &table)) != kStatusOk) {
    return status;
  }

  out->entries_ = std::move(table);

  return kStatusOk;
}

Status HeaderReader::CheckMagic(const uint8_t* data, size_t len) {
  if (len < kArchiveMagicLength) {
    return kStatusErrBufferTooSmall;
  }
  // In practice the magic is always at the start of the header, but for consistency with other
  // accesses we offset |data| by |kChunkArchiveMagicOffset|.
  if (memcmp(data + kChunkArchiveMagicOffset, kChunkArchiveMagic, kArchiveMagicLength)) {
    FX_SLOG(ERROR, "File magic doesn't match");
    return kStatusErrIoDataIntegrity;
  }
  return kStatusOk;
}

Status HeaderReader::CheckVersion(const uint8_t* data, size_t len) {
  if (len < kChunkArchiveVersionOffset + sizeof(ArchiveVersionType)) {
    return kStatusErrBufferTooSmall;
  }
  const ArchiveVersionType& version =
      reinterpret_cast<const ArchiveVersionType*>(data + kChunkArchiveVersionOffset)[0];
  if (version != kVersion) {
    FX_SLOG(ERROR, "Unsupported archive version", FX_KV("actual", version),
            FX_KV("expected", kVersion));
    return kStatusErrInvalidArgs;
  }
  return kStatusOk;
}

Status HeaderReader::CheckChecksum(const uint8_t* data, size_t len) {
  if (len < kChunkArchiveHeaderCrc32Offset + sizeof(uint32_t)) {
    return kStatusErrBufferTooSmall;
  }
  uint32_t crc = reinterpret_cast<const uint32_t*>(data + kChunkArchiveHeaderCrc32Offset)[0];
  uint32_t expected_crc = ComputeChecksum(data, len);
  if (crc != expected_crc) {
    FX_SLOG(ERROR, "Bad archive checksum");
    return kStatusErrIoDataIntegrity;
  }
  return kStatusOk;
}

Status HeaderReader::GetNumChunks(const uint8_t* data, size_t len, ChunkCountType* num_chunks_out) {
  if (len < kChunkArchiveNumChunksOffset + sizeof(ChunkCountType)) {
    return kStatusErrBufferTooSmall;
  }
  *num_chunks_out = reinterpret_cast<const ChunkCountType*>(data + kChunkArchiveNumChunksOffset)[0];
  return kStatusOk;
}

Status HeaderReader::ParseSeekTable(const uint8_t* data, size_t len, size_t file_length,
                                    fbl::Array<SeekTableEntry>* entries_out) {
  ChunkCountType num_chunks;
  Status status = GetNumChunks(data, len, &num_chunks);
  if (status != kStatusOk) {
    return status;
  }
  size_t header_end = kChunkArchiveSeekTableOffset + (num_chunks * sizeof(SeekTableEntry));
  if (len < header_end) {
    FX_SLOG(ERROR, "Invalid archive. Header too small for seek table size");
    return kStatusErrIoDataIntegrity;
  }

  const SeekTableEntry* entries =
      reinterpret_cast<const SeekTableEntry*>(data + kChunkArchiveSeekTableOffset);
  fbl::Array<SeekTableEntry> table(new SeekTableEntry[num_chunks], num_chunks);
  for (size_t i = 0; i < num_chunks; ++i) {
    table[i] = entries[i];
  }

  if ((status = CheckSeekTable(table, header_end, file_length)) != kStatusOk) {
    return status;
  }

  *entries_out = std::move(table);
  return kStatusOk;
}

Status HeaderReader::CheckSeekTable(const fbl::Array<SeekTableEntry>& table, size_t header_end,
                                    size_t file_length) {
  for (size_t i = 0; i < table.size(); ++i) {
    const SeekTableEntry* prev = i > 0 ? &table[i - 1] : nullptr;
    Status status;
    if ((status = CheckSeekTableEntry(table[i], prev, header_end, file_length)) != kStatusOk) {
      FX_SLOG(ERROR, "Invalid archive. Bad seek table entry", FX_KV("entry", i));
      return status;
    }
  }
  return kStatusOk;
}

Status HeaderReader::CheckSeekTableEntry(const SeekTableEntry& entry, const SeekTableEntry* prev,
                                         size_t header_end, size_t file_length) {
  if (entry.compressed_size == 0 || entry.decompressed_size == 0) {
    // Invariant I4
    FX_SLOG(ERROR, "Zero-sized entry");
    return kStatusErrIoDataIntegrity;
  } else if (entry.compressed_offset < header_end) {
    // Invariant I1
    FX_SLOG(ERROR, "Invalid archive. Chunk overlaps with header");
    return kStatusErrIoDataIntegrity;
  }
  uint64_t compressed_end;
  if (add_overflow(entry.compressed_offset, entry.compressed_size, &compressed_end)) {
    FX_SLOG(ERROR, "Compressed frame too big");
    return kStatusErrIoDataIntegrity;
  } else if (compressed_end > file_length) {
    // Invariant I5
    FX_SLOG(ERROR, "Invalid archive. Chunk exceeds file length");
    return kStatusErrIoDataIntegrity;
  }
  [[maybe_unused]] uint64_t decompressed_end;
  if (add_overflow(entry.decompressed_offset, entry.decompressed_size, &decompressed_end)) {
    FX_SLOG(ERROR, "Decompressed frame too big");
    return kStatusErrIoDataIntegrity;
  }
  if (prev != nullptr) {
    if (prev->decompressed_offset + prev->decompressed_size != entry.decompressed_offset) {
      // Invariant I2
      FX_SLOG(ERROR, "Invalid archive. Decompressed chunks are non-contiguous");
      return kStatusErrIoDataIntegrity;
    }
    if (prev->compressed_offset + prev->compressed_size > entry.compressed_offset) {
      // Invariant I3
      FX_SLOG(ERROR, "Invalid archive. Chunks are non-monotonic");
      return kStatusErrIoDataIntegrity;
    }
  } else if (entry.decompressed_offset != 0) {
    // Invariant I0
    FX_SLOG(ERROR, "Invalid archive. Decompressed chunks must start at offset 0");
    return kStatusErrIoDataIntegrity;
  }
  return kStatusOk;
}

uint32_t HeaderReader::ComputeChecksum(const uint8_t* header, size_t header_length) {
  constexpr size_t kOffsetAfterChecksum = kChunkArchiveHeaderCrc32Offset + sizeof(uint32_t);
  ZX_DEBUG_ASSERT(kOffsetAfterChecksum < header_length);

  // Independently compute a checksum for the bytes before and after the CRC32 slot, using the first
  // as a seed for the second to combine them.
  constexpr uint32_t seed = 0u;
  uint32_t first_crc = crc32(seed, header, kChunkArchiveHeaderCrc32Offset);
  uint32_t crc =
      crc32(first_crc, header + kOffsetAfterChecksum, header_length - kOffsetAfterChecksum);
  return crc;
}

// HeaderWriter

Status HeaderWriter::Create(void* dst, size_t dst_len, size_t num_frames, HeaderWriter* out) {
  if (num_frames > kChunkArchiveMaxFrames) {
    return kStatusErrInvalidArgs;
  } else if (dst_len < MetadataSizeForNumFrames(num_frames)) {
    return kStatusErrBufferTooSmall;
  }
  *out = HeaderWriter(dst, dst_len, num_frames);
  return kStatusOk;
}

HeaderWriter::HeaderWriter(void* dst, size_t dst_len, size_t num_frames)
    : dst_(static_cast<uint8_t*>(dst)) {
  ZX_DEBUG_ASSERT(num_frames <= kChunkArchiveMaxFrames);

  num_frames_ = static_cast<ChunkCountType>(num_frames);

  dst_length_ = MetadataSizeForNumFrames(num_frames);
  ZX_DEBUG_ASSERT(dst_len >= dst_length_);
  bzero(dst_, dst_length_);
}

Status HeaderWriter::AddEntry(const SeekTableEntry& entry) {
  if (current_frame_ == num_frames_) {
    return kStatusErrBadState;
  }

  std::optional<SeekTableEntry> prev = std::nullopt;
  if (current_frame_ > 0) {
    prev = SeekTableEntry{};
    const uint8_t* prev_data =
        dst_ + kChunkArchiveSeekTableOffset + (current_frame_ - 1) * sizeof(SeekTableEntry);
    std::memcpy(&*prev, prev_data, sizeof(SeekTableEntry));
  }

  size_t header_end = kChunkArchiveSeekTableOffset + (num_frames_ * sizeof(SeekTableEntry));
  // Since we don't know yet how long the compressed file will be, simply pass UINT64_MAX
  // as the upper bound for the file length. This effectively disables checking compressed frames
  // against the file size.
  Status status = HeaderReader::CheckSeekTableEntry(entry, prev.has_value() ? &*prev : nullptr,
                                                    header_end, UINT64_MAX);
  if (status != kStatusOk) {
    return kStatusErrInvalidArgs;
  }

  uint8_t* next_entry =
      dst_ + kChunkArchiveSeekTableOffset + (current_frame_ * sizeof(SeekTableEntry));
  std::memcpy(next_entry, &entry, sizeof(SeekTableEntry));
  ++current_frame_;
  return kStatusOk;
}

Status HeaderWriter::Finalize() {
  if (current_frame_ < num_frames_) {
    return kStatusErrBadState;
  }

  // In practice the magic is always at the start of the header, but for consistency with other
  // accesses we offset |data| by |kChunkArchiveMagicOffset|.
  memcpy(dst_, kChunkArchiveMagic, kArchiveMagicLength);
  reinterpret_cast<ArchiveVersionType*>(dst_ + kChunkArchiveVersionOffset)[0] = kVersion;
  reinterpret_cast<ChunkCountType*>(dst_ + kChunkArchiveNumChunksOffset)[0] = num_frames_;

  // Always compute checkum last.
  reinterpret_cast<uint32_t*>(dst_ + kChunkArchiveHeaderCrc32Offset)[0] =
      HeaderReader::ComputeChecksum(dst_, dst_length_);

  return kStatusOk;
}

}  // namespace chunked_compression
