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

#include <cstddef>
#include <cstdint>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_macros.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "constants/labels.h"
#include "formats/asset_box.h"
#include "formats/byte_range.h"
#include "formats/jpeg/extractor.h"
#include "formats/jpeg/testing/jumbf_creator.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/box_builder.h"
#include "jumbf/constants.h"
#include "jumbf/encode_params.h"
#include "riegeli/base/object.h"
#include "riegeli/bytes/limiting_writer.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::ElementsAre;
using ::testing::HasSubstr;
using ::testing::Optional;

// Creates a jumbf SuperBox that looks superficially like a Manifest Store.
absl::StatusOr<std::string> CreateFakeManifestStore(size_t content_size) {
  jumbf::SuperBoxBuilder manifest_store_builder(
      kManifestStoreUuid,
      jumbf::DescriptionBoxOptions{.label = absl::Cord(kManifestStoreLabel)});
  ABSL_RETURN_IF_ERROR(manifest_store_builder.AddContent(
      jumbf::kBinaryDataBoxType, absl::Cord(std::string(content_size, 'x'))));
  ABSL_ASSIGN_OR_RETURN(jumbf::BuiltSuperBox manifest_store_box,
                        std::move(manifest_store_builder).Finalize());
  return std::string(std::move(manifest_store_box).AsCord());
}

TEST(App11IOTest, WriteSmallPayload) {
  auto manifest_store_or = CreateFakeManifestStore(/*content_size=*/100);
  ABSL_ASSERT_OK(manifest_store_or);
  const auto& manifest_store = *manifest_store_or;

  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  ABSL_ASSERT_OK(
      WriteJpegApp11Payload(/*segment_id=*/30, manifest_store, output));
  ASSERT_TRUE(output.Close());

  riegeli::StringReader<absl::string_view> input(output_s);
  JpegExtractor extractor;

  EXPECT_THAT(extractor.ExtractManifestStore(input),
              IsOkAndHolds(manifest_store));

  ASSERT_TRUE(input.Seek(0));

  EXPECT_THAT(extractor.ExtractManifestStoreLocation(input, {}),
              IsOkAndHolds(Optional(ByteRange{.offset = 0, .length = 158})));

  ASSERT_TRUE(input.Seek(0));

  EXPECT_THAT(
      extractor.ExtractBoxes(input, {}),
      IsOkAndHolds(ElementsAre(AssetBox{
          .identifier = "C2PA", .byte_range = {.offset = 0, .length = 158}})));
}

TEST(App11IOTest, WriteLargePayload) {
  auto manifest_store_or = CreateFakeManifestStore(/*content_size=*/250000);
  ABSL_ASSERT_OK(manifest_store_or);
  const auto& manifest_store = *manifest_store_or;

  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  ABSL_ASSERT_OK(
      WriteJpegApp11Payload(/*segment_id=*/30, manifest_store, output));
  ASSERT_TRUE(output.Close());

  riegeli::StringReader<absl::string_view> input(output_s);

  JpegExtractor extractor;
  EXPECT_THAT(extractor.ExtractManifestStore(input),
              IsOkAndHolds(manifest_store));

  ASSERT_TRUE(input.Seek(0));

  EXPECT_THAT(extractor.ExtractManifestStoreLocation(input, {}),
              IsOkAndHolds(Optional(ByteRange{.offset = 0, .length = 250118})));

  ASSERT_TRUE(input.Seek(0));

  EXPECT_THAT(extractor.ExtractBoxes(input, {}),
              IsOkAndHolds(ElementsAre(
                  AssetBox{.identifier = "C2PA",
                           .byte_range = {.offset = 0, .length = 250118}})));
}

TEST(App11IOTest, WriteInvalidPayload) {
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(
      WriteJpegApp11Payload(/*segment_id=*/30, std::string(6, '\0'), output),
      StatusIs(absl::StatusCode::kDataLoss, HasSubstr("Failed to read tbox")));
}

TEST(App11IOTest, WriteInvalidJumbfPayload) {
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(
      WriteJpegApp11Payload(/*segment_id=*/30, std::string(60, '\0'), output),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("invalid jumbf box")));
}

TEST(App11IOTest, WritePayloadWithXlbox) {
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  ABSL_EXPECT_OK(WriteJpegApp11Payload(
      /*segment_id=*/30, CreateJumbf({.force_xlbox = true}), output));
  ASSERT_TRUE(output.Close());
}

TEST(App11IOTest, WritePayloadFails) {
  auto manifest_store_or = CreateFakeManifestStore(/*content_size=*/100);
  ABSL_ASSERT_OK(manifest_store_or);
  const auto& manifest_store = *manifest_store_or;

  std::string output_s;
  riegeli::StringWriter<> string_writer(&output_s);
  // Limit the writer to 1 byte, forcing a failure.
  riegeli::LimitingWriter<> limited_writer(
      &string_writer, riegeli::LimitingWriterBase::Options().set_max_length(1));
  EXPECT_THAT(
      WriteJpegApp11Payload(/*segment_id=*/30, manifest_store, limited_writer),
      StatusIs(absl::StatusCode::kResourceExhausted));
  EXPECT_FALSE(limited_writer.Close());
}

TEST(App11IOTest, WritePayloadFailsImmediately) {
  auto manifest_store_or = CreateFakeManifestStore(/*content_size=*/100);
  ABSL_ASSERT_OK(manifest_store_or);
  const auto& manifest_store = *manifest_store_or;

  riegeli::StringWriter<> failing_writer(riegeli::kClosed);
  failing_writer.Fail(absl::InternalError("Test failure"));
  EXPECT_THAT(
      WriteJpegApp11Payload(/*segment_id=*/30, manifest_store, failing_writer),
      StatusIs(absl::StatusCode::kInternal, HasSubstr("Test failure")));
  EXPECT_FALSE(failing_writer.Close());
}

TEST(App11IOTest, CalculateSizeOneSegment) {
  EXPECT_EQ(CalculateTotalJpegApp11SegmentsSize(1000), 1012);
}

TEST(App11IOTest, CalculateSizeExactSingleSegmentSize) {
  EXPECT_EQ(CalculateTotalJpegApp11SegmentsSize(65008), 65020);
}

TEST(App11IOTest, CalculateSizeMultipleSegments) {
  EXPECT_EQ(CalculateTotalJpegApp11SegmentsSize(65200), 65232);
}

TEST(App11IOTest, CalculateSizeOf64BitPayload) {
  EXPECT_EQ(CalculateTotalJpegApp11SegmentsSize(
                static_cast<uint64_t>(UINT32_MAX) + 1000),
            4296818435);
}

}  // namespace
}  // namespace credentio
