/*
 * Copyright 2026 Rive
 */

#include "rive/decoders/bitmap_decoder.hpp"
#include "rive/gpu_texture_format.hpp"

#include <cstdio>
#include <cstring>
#include <memory>

// Forward declarations for Ericsson ETCPACK's etcdec.cxx (built as part of
// rive_decoders when RIVE_ETC_DECODER is set). Each entrypoint writes one 4x4
// block into a planar RGBA buffer at byte offsets +0/+1/+2 (RGB) and +3 (A).
extern void decompressBlockETC2c(
    unsigned int block_part1,
    unsigned int block_part2,
    unsigned char* img,
    int width,
    int height,
    int startx,
    int starty,
    int channels);
extern void decompressBlockAlphaC(
    unsigned char* data,
    unsigned char* img,
    int width,
    int height,
    int ix,
    int iy,
    int channels);

namespace
{
unsigned int readBE32(const uint8_t* p)
{
  return (static_cast<unsigned int>(p[0]) << 24) |
         (static_cast<unsigned int>(p[1]) << 16) |
         (static_cast<unsigned int>(p[2]) << 8) |
         static_cast<unsigned int>(p[3]);
}
} // namespace

// Decodes ETC2 RGBA8 (16 bytes/block: 8 bytes EAC alpha + 8 bytes ETC2 RGB).
std::unique_ptr<Bitmap> decode_etc_texture(
    const uint8_t* blocks,
    size_t byteCount,
    uint32_t width,
    uint32_t height,
    rive::GPUTextureFormat format)
{
  if (format != rive::GPUTextureFormat::etc2 || width == 0 || height == 0)
  {
    return nullptr;
  }

  const uint32_t paddedW = (width + 3u) & ~3u;
  const uint32_t paddedH = (height + 3u) & ~3u;
  const uint32_t blocksX = paddedW / 4u;
  const uint32_t blocksY = paddedH / 4u;
  const size_t expectedBytes = static_cast<size_t>(blocksX) * blocksY * 16u;
  if (byteCount != expectedBytes)
  {
    fprintf(
        stderr,
        "DecodeEtcTexture - byteCount %zu != expected %zu for %ux%u\n",
        byteCount,
        expectedBytes,
        width,
        height);
    return nullptr;
  }

  const size_t paddedPixels = static_cast<size_t>(paddedW) *
                              static_cast<size_t>(paddedH);
  auto padded = std::make_unique<uint8_t[]>(paddedPixels * 4);

  const uint8_t* src = blocks;
  for (uint32_t by = 0; by < blocksY; ++by)
  {
    for (uint32_t bx = 0; bx < blocksX; ++bx)
    {
      const int startX = static_cast<int>(bx * 4u);
      const int startY = static_cast<int>(by * 4u);
      decompressBlockAlphaC(
          const_cast<uint8_t*>(src),
          padded.get() + 3,
          static_cast<int>(paddedW),
          static_cast<int>(paddedH),
          startX,
          startY,
          4);
      const unsigned int p1 = readBE32(src + 8);
      const unsigned int p2 = readBE32(src + 12);
      decompressBlockETC2c(
          p1,
          p2,
          padded.get(),
          static_cast<int>(paddedW),
          static_cast<int>(paddedH),
          startX,
          startY,
          4);
      src += 16;
    }
  }

  // Crop padded RGBA grid down to (width, height).
  const size_t outPixels = static_cast<size_t>(width) *
                           static_cast<size_t>(height);
  auto pixels = std::make_unique<uint8_t[]>(outPixels * 4);
  for (uint32_t y = 0; y < height; ++y)
  {
    std::memcpy(
        pixels.get() + static_cast<size_t>(y) * width * 4,
        padded.get() + static_cast<size_t>(y) * paddedW * 4,
        static_cast<size_t>(width) * 4);
  }

  return std::make_unique<Bitmap>(
      width,
      height,
      outPixels * 4,
      Bitmap::PixelFormat::RGBA,
      std::move(pixels));
}
