// 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/tiff/hasher.h"

#include <algorithm>
#include <cstdint>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/statusor.h"
#include "bindings/input_hasher.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/writer.h"
#include "riegeli/endian/endian_writing.h"

namespace credentio {

namespace {
// It's fine to use a fixed kMaxChunkBytes here, because the embedder will work
// with any size greater than 8 bytes. (Larger sizes are more efficient.)
constexpr uint64_t kMaxChunkBytes = 1048576;  // 1 MiB

template <typename T>
absl::StatusOr<std::string> UintToString(T value, bool is_big_endian) {
  std::string buffer(sizeof(T), '\0');
  if constexpr (sizeof(T) == 2 || sizeof(T) == 4) {
    if (is_big_endian) {
      riegeli::WriteBigEndian<T>(value, buffer.data());
    } else {
      riegeli::WriteLittleEndian<T>(value, buffer.data());
    }
  } else {
    return absl::InvalidArgumentError("Unsupported type size");
  }
  return buffer;
}

template <typename T>
absl::Status HashWrite(T value, bool is_big_endian, InputHasher& hasher,
                       riegeli::Writer& writer) {
  ABSL_ASSIGN_OR_RETURN(std::string buffer, UintToString(value, is_big_endian));
  hasher.Update(buffer);
  if (!writer.Write(buffer)) {
    return absl::DataLossError("failed to write to writer");
  }
  return absl::OkStatus();
}

template <typename T>
absl::Status Write(T value, bool is_big_endian, riegeli::Writer& writer) {
  ABSL_ASSIGN_OR_RETURN(std::string buffer, UintToString(value, is_big_endian));
  if (!writer.Write(buffer)) {
    return absl::DataLossError("failed to write to writer");
  }
  return absl::OkStatus();
}

}  // namespace

absl::Status ReadHash(riegeli::Reader& reader, int64_t length,
                      InputHasher& hasher) {
  uint64_t remaining_length_to_copy = length;
  while (remaining_length_to_copy > 0) {
    std::string chunk;
    auto chunk_size = std::min(remaining_length_to_copy, kMaxChunkBytes);
    if (!reader.Read(chunk_size, chunk)) {
      return absl::DataLossError("Failed to read from source TIFF");
    }
    hasher.Update(chunk);
    remaining_length_to_copy -= chunk_size;
  }
  return absl::OkStatus();
}

absl::Status ReadHashWrite(riegeli::Reader& reader, int64_t length,
                           InputHasher& hasher, riegeli::Writer& writer) {
  uint64_t remaining_length_to_copy = length;
  while (remaining_length_to_copy > 0) {
    std::string chunk;
    auto chunk_size = std::min(remaining_length_to_copy, kMaxChunkBytes);
    if (!reader.Read(chunk_size, chunk)) {
      return absl::DataLossError("Failed to read from source TIFF");
    }
    hasher.Update(chunk);
    if (!writer.Write(chunk)) {
      return absl::DataLossError("Failed to write to destination TIFF");
    }
    remaining_length_to_copy -= chunk_size;
  }
  return absl::OkStatus();
}

absl::Status HashWrite16(uint16_t value, bool is_big_endian,
                         InputHasher& hasher, riegeli::Writer& writer) {
  return HashWrite<uint16_t>(value, is_big_endian, hasher, writer);
}
absl::Status HashWrite32(uint32_t value, bool is_big_endian,
                         InputHasher& hasher, riegeli::Writer& writer) {
  return HashWrite<uint32_t>(value, is_big_endian, hasher, writer);
}

absl::Status Write32(uint32_t value, bool is_big_endian,
                     riegeli::Writer& writer) {
  return Write<uint32_t>(value, is_big_endian, writer);
}

}  // namespace credentio
