// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "formats/jpeg/box_header.h"

#include <cstdint>
#include <ostream>
#include <string>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/endian/endian_reading.h"

namespace credentio {
namespace {

const uint32_t kJpegStartMarker = 0xffd8;
const uint32_t kJpegEndMarker = 0xffd9;

// Converts a JPEG marker to a human readable label.
// Sourced from Table B.1 of ISO/IEC 10918-1:1994
std::string ConvertMarkerToLabel(uint16_t marker) {
  if (0xff00 != (marker & 0xff00) || marker == 0xffff) {
    // Markers are always 0xFFXX
    // 0xFFFF is not a valid JPEG marker
    return absl::StrFormat("%04x", marker);
  }
  if (0x00c0 == (marker & 0x00f0)) {
    switch (marker) {
      case 0xffc4:
        return "DHT";  // Define Huffman Table(s)
      case 0xffc8:
        return "JPG";  // Reserved for JPG extensions
      case 0xffcc:
        return "DAC";  // Define arithmetic coding conditioning(s)
      default:
        // Start Of Frame markers labeled numerically
        return absl::StrFormat("SOF%d", (marker & 0x000f));
    }
  }
  if (0x00d0 == (marker & 0x00f0)) {
    switch (marker) {
      case 0xffd8:
        return "SOI";  // Start of Image
      case 0xffd9:
        return "EOI";  // End of Image
      case 0xffda:
        return "SOS";  // Start of Scan
      case 0xffdb:
        return "DQT";  // Define Quantization Table(s)
      case 0xffdc:
        return "DNL";  // Define Number of Lines
      case 0xffdd:
        return "DRI";  // Define Restart Interval
      case 0xffde:
        return "DHP";  // Define Hierarchical Progression
      case 0xffdf:
        return "EXP";  // Expand reference component(s)
      default:
        // Restart with modulo 8 markers labeled numerically
        return absl::StrFormat("RST%d", (marker & 0x000f));
    }
  }
  if (0x00e0 == (marker & 0x00f0)) {
    // Reserved for APP markers labeled numerically
    return absl::StrFormat("APP%d", (marker & 0x000f));
  }
  if (0x00f0 == (marker & 0x00f0)) {
    switch (marker) {
      case 0xfffe:
        return "COM";  // Comment
      default:
        // Reserved for JPEG extensions labeled numerically
        return absl::StrFormat("JPG%d", (marker & 0x000f));
    }
  }
  if (marker == 0xff01) {
    return "TEM";  // For temporary private use in arithmetic coding
  }
  return "RES";  // Reserved
}
}  // namespace

std::string JpegBoxHeader::label() const {
  return ConvertMarkerToLabel(this->type);
}

absl::StatusOr<JpegBoxHeader> ConsumeJpegBoxHeader(riegeli::Reader& input) {
  JpegBoxHeader b = {.offset = input.pos()};
  if (!riegeli::ReadBigEndian<uint16_t>(input, b.type)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read type"));
  }

  if (0xff00 != (b.type & 0xff00) || b.type == 0xffff) {
    // Invalid marker.
    return absl::InvalidArgumentError(
        absl::StrFormat("Invalid JPEG marker: %d", b.type));
  }

  if (b.type == kJpegStartMarker || b.type == kJpegEndMarker ||
      b.type == 0xff01 || (b.type >= 0xffd0 && b.type <= 0xffd7)) {
    // No payload.
    b.size = sizeof(uint16_t);
    return b;
  }

  uint16_t chunk_size;
  if (!riegeli::ReadBigEndian<uint16_t>(input, chunk_size)) {
    return input.StatusOrAnnotate(absl::DataLossError("Failed to read size"));
  }
  if (chunk_size < 2) {
    return absl::InvalidArgumentError(
        absl::StrFormat("Invalid JPEG segment size: %d", chunk_size));
  }
  b.size = chunk_size + sizeof(b.type);
  return b;
}

void PrintTo(const JpegBoxHeader& x, ::std::ostream* os) {
  *os << absl::StrCat("{type: ", x.type, ", offset: ", x.offset,
                      ", size: ", x.size, ", label: \"", x.label(), "\"}");
}

}  // namespace credentio
