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

#include <cstdint>
#include <vector>

#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "formats/jpeg/reader.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "jumbf/constants.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

using ::absl_testing::StatusIs;
using ::testing::ElementsAre;
using ::testing::HasSubstr;
using ::testing::IsEmpty;
using ::testing::SizeIs;

class TestC2paSegmentHandler : public C2paSegmentHandler {
 public:
  std::vector<std::vector<JpegSegment>> AllRecorded() const {
    absl::btree_set<uint16_t> segment_ids;
    for (const auto& [segment_id, segments] : GetSegmentMap()) {
      segment_ids.insert(segment_id);
    }

    std::vector<std::vector<JpegSegment>> result;
    for (uint16_t segment_id : segment_ids) {
      result.push_back(GetSegmentMap().at(segment_id));
    }
    return result;
  }

  absl::btree_set<uint16_t> AllIgnored() const {
    return absl::btree_set<uint16_t>(GetIgnoredSegmentIds().begin(),
                                     GetIgnoredSegmentIds().end());
  }
};

TEST(RecordSegmentTest, DoesNotRecordSegmentWithoutApp11Info) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());
}

TEST(RecordSegmentTest, DoesNotRecordSegmentIdZero) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(
      JpegSegment{.app11_info = JpegApp11Segment{.segment_id = 0}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());
}

TEST(RecordSegmentTest, DoesNotRecordSegmentWithoutJumbfData) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(
      JpegSegment{.app11_info = JpegApp11Segment{.segment_id = 1}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());
}

TEST(RecordSegmentTest, DoesNotRecordSegmentIncorrectTbox) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .app11_info = JpegApp11Segment{
          .segment_id = 1, .jumbf_data = JpegJumbfData{.tbox = 0x1234}}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());
}

TEST(RecordSegmentTest, RecordSegment) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .app11_info = JpegApp11Segment{
          .segment_id = 1,
          .jumbf_data = JpegJumbfData{.tbox = jumbf::kSuperBoxType}}});
  EXPECT_THAT(
      handler.AllRecorded(),
      ElementsAre(ElementsAre(JpegSegment{
          .app11_info = JpegApp11Segment{
              .segment_id = 1,
              .jumbf_data = JpegJumbfData{.tbox = jumbf::kSuperBoxType}}})));
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());
}

TEST(RecordSegmentTest, DoesNotRecordNextSegmentIncorrectSequence) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .tbox = jumbf::kSuperBoxType,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .tbox = jumbf::kSuperBoxType,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));
}

TEST(RecordSegmentTest, DoesNotRecordNextSegmentNotContiguous) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 100,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .tbox = jumbf::kSuperBoxType,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .offset = 200,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 2,
                                     .jumbf_data = JpegJumbfData{
                                         .tbox = jumbf::kSuperBoxType,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));
}

TEST(RecordSegmentTest, DoesNotRecordNextSegmentDifferentLbox) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 100,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .offset = 110,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 2,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 20,
                                         .tbox = jumbf::kSuperBoxType,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));
}

TEST(RecordSegmentTest, DoesNotRecordNextSegmentDifferentXlbox) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 100,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 1,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 10,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .offset = 110,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 2,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 1,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 20,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));
}

TEST(RecordSegmentTest, RecordsNextSegment) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 100,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .offset = 110,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 2,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(),
              ElementsAre(ElementsAre(
                  JpegSegment{
                      .offset = 100,
                      .length = 10,
                      .app11_info =
                          JpegApp11Segment{.segment_id = 1,
                                           .sequence_number = 1,
                                           .jumbf_data =
                                               JpegJumbfData{
                                                   .lbox = 10,
                                                   .tbox = jumbf::kSuperBoxType,
                                                   .xlbox = 0,
                                               }},
                  },
                  JpegSegment{
                      .offset = 110,
                      .length = 10,
                      .app11_info =
                          JpegApp11Segment{.segment_id = 1,
                                           .sequence_number = 2,
                                           .jumbf_data =
                                               JpegJumbfData{
                                                   .lbox = 10,
                                                   .tbox = jumbf::kSuperBoxType,
                                                   .xlbox = 0,
                                               }},
                  })));
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());
}

TEST(RecordSegmentTest, DoesNotRecordIgnoredSegment) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 100,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .offset = 110,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));

  handler.RecordSegment(JpegSegment{
      .offset = 210,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});

  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));
}

TEST(RecordSegmentTest, DoesNotRecordMoreThanMaxSegmentsPerId) {
  TestC2paSegmentHandler handler;
  for (int i = 1; i <= 1000; ++i) {
    handler.RecordSegment(JpegSegment{
        .offset = static_cast<uint64_t>((i - 1) * 10),
        .length = 10,
        .app11_info =
            JpegApp11Segment{.segment_id = 1,
                             .sequence_number = static_cast<uint32_t>(i),
                             .jumbf_data = JpegJumbfData{
                                 .lbox = 10,
                                 .tbox = jumbf::kSuperBoxType,
                                 .xlbox = 0,
                             }}});
  }
  EXPECT_THAT(handler.AllRecorded(), SizeIs(1));
  EXPECT_THAT(handler.AllRecorded().front(), SizeIs(1000));
  EXPECT_THAT(handler.AllIgnored(), IsEmpty());

  handler.RecordSegment(JpegSegment{
      .offset = 10000,
      .length = 10,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1001,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 10,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});
  EXPECT_THAT(handler.AllRecorded(), IsEmpty());
  EXPECT_THAT(handler.AllIgnored(), ElementsAre(1));
}

TEST(GetC2paSegmentTest, RejectsDeclaredPayloadSizeTooLarge) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 0,
      .length = 100,
      .app11_info = JpegApp11Segment{
          .segment_id = 1,
          .sequence_number = 1,
          .payload_offset = 0,
          .payload_length = 10,
          .jumbf_data = JpegJumbfData{
              .lbox = 1024 * 1024 * 10 + 1,  // > kMaxPayloadSize (10 MiB)
              .tbox = jumbf::kSuperBoxType,
              .xlbox = 0,
          }}});
  std::string data(10, 'A');
  riegeli::StringReader input(data);
  EXPECT_THAT(handler.GetC2paSegment(input),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Declared JUMBF payload size is invalid")));
}

TEST(GetC2paSegmentTest, RejectsDeclaredPayloadSizeZero) {
  TestC2paSegmentHandler handler;
  handler.RecordSegment(JpegSegment{
      .offset = 0,
      .length = 100,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .payload_offset = 0,
                                     .payload_length = 10,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = 0,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                     }}});
  std::string data(10, 'A');
  riegeli::StringReader input(data);
  EXPECT_THAT(handler.GetC2paSegment(input),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Declared JUMBF payload size is invalid")));
}

TEST(GetC2paSegmentTest, RejectsCumulativePayloadSizeExceedingMax) {
  TestC2paSegmentHandler handler;
  const uint64_t kSixMiB = 6 * 1024 * 1024;
  const uint64_t kFiveMiB = 5 * 1024 * 1024;
  const uint64_t kTenMiB = 10 * 1024 * 1024;
  handler.RecordSegment(JpegSegment{
      .offset = 0,
      .length = 100,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 1,
                                     .payload_offset = 0,
                                     .payload_length = kSixMiB,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = kTenMiB,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                         .payload_offset = 0,
                                         .payload_length = kSixMiB,
                                     }}});
  handler.RecordSegment(JpegSegment{
      .offset = 100,
      .length = 100,
      .app11_info = JpegApp11Segment{.segment_id = 1,
                                     .sequence_number = 2,
                                     .payload_offset = kSixMiB,
                                     .payload_length = kFiveMiB,
                                     .jumbf_data = JpegJumbfData{
                                         .lbox = kTenMiB,
                                         .tbox = jumbf::kSuperBoxType,
                                         .xlbox = 0,
                                         .payload_offset = kSixMiB,
                                         .payload_length = kFiveMiB,
                                     }}});
  std::string data(kSixMiB, 'A');
  riegeli::StringReader input(data);
  EXPECT_THAT(handler.GetC2paSegment(input),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("JPEG segment is too large to extract")));
}

}  // namespace
}  // namespace credentio
