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

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

#include "absl/log/absl_check.h"
#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/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/notification.h"
#include "async/async_context.h"
#include "formats/byte_range.h"
#include "formats/jpeg/extractor.h"
#include "formats/jpeg/reader.h"
#include "formats/jpeg/testing/jpeg_creator.h"
#include "formats/jpeg/testing/jumbf_creator.h"
#include "generator/generator.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/generator.pb.h"
#include "proto/manifest.pb.h"
#include "proto/validation_status.pb.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"
#include "testing/fake_manifest_store_generator.h"
#include "testing/nonprod_generator.h"
#include "testing/nonprod_validator.h"
#include "testing/proto_test_utils.h"
#include "validator/asset_validator.h"
#include "validator/result.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::credentio_testing::ParseTextProtoOrDie;
using ::credentio_testing::PartiallyEqualsProto;
using ::testing::AllOf;
using ::testing::Contains;
using ::testing::Field;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::IsEmpty;
using ::testing::Not;
using ::testing::Optional;
using ::testing::SizeIs;
using ::testing::StartsWith;

constexpr char kExifData[] = "Exif\0\0fake exif data";
constexpr absl::string_view kExifPayload(kExifData, sizeof(kExifData) - 1);

// Returns a JPEG segment with the given marker and payload.
std::string Segment(uint16_t marker, absl::string_view payload) {
  const uint16_t length = static_cast<uint16_t>(payload.size() + 2);
  return absl::StrCat(
      std::string({static_cast<char>(marker >> 8), static_cast<char>(marker),
                   static_cast<char>(length >> 8), static_cast<char>(length)}),
      payload);
}

// Returns a minimal JPEG image: SOI, APP0 (JFIF), APP1 (Exif), DQT, EOI.
std::string CreateJpegImage() {
  return CreateJpeg(JpegParams{
      .payload = {
          Segment(0xffe0,
                  absl::string_view("JFIF\0\x01\x02\0\0\x01\0\x01\0\0", 14)),
          Segment(0xffe1, kExifPayload),
          Segment(0xffdb, std::string(65, '\x01')),
      }});
}

GenerateManifestStoreRequest CreateRequest() {
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");
  return request;
}

// Returns a fake manifest store: a JUMBF box with a payload of the given size.
std::string CreateFakeManifestStore(size_t payload_size = 32) {
  return CreateJumbf({.payload = std::string(payload_size, 'm')});
}

// Returns the byte offset of the Exif payload in `jpeg`.
size_t ExifOffset(absl::string_view jpeg) {
  size_t offset = jpeg.find(kExifPayload);
  ABSL_CHECK_NE(offset, absl::string_view::npos);
  return offset;
}

class JpegWriterTest : public ::testing::Test {
 protected:
  void SetUp() override {
    auto generator = CreateNonProdManifestStoreGenerator();
    ABSL_CHECK_OK(generator);
    generator_ = *std::move(generator);
    writer_ = std::make_unique<JpegWriter>(generator_.get());

    auto validator = CreateNonProdValidator();
    ABSL_CHECK_OK(validator);
    validator_ = *std::move(validator);
  }

  // Validates `asset` and returns the active manifest validation statuses.
  absl::StatusOr<ValidationStatusSet> Validate(absl::string_view asset) {
    riegeli::StringReader reader(asset);
    ABSL_ASSIGN_OR_RETURN(std::unique_ptr<ValidationResult> result,
                          validator_->Validate(reader, "image/jpeg"));
    return result->proto().active_manifest().validation();
  }

  // Expects `asset` to contain a manifest store and to be valid.
  void ExpectValid(absl::string_view asset) {
    riegeli::StringReader reader(asset);
    EXPECT_THAT(
        JpegExtractor().ExtractManifestStoreLocation(reader, {}),
        IsOkAndHolds(Optional(AllOf(Field(&ByteRange::offset, Gt(0)),
                                    Field(&ByteRange::length, Gt(0))))));

    absl::StatusOr<ValidationStatusSet> validation = Validate(asset);
    ABSL_ASSERT_OK(validation);
    EXPECT_THAT(validation->failures(), IsEmpty());
    EXPECT_THAT(validation->successes(),
                Contains(PartiallyEqualsProto(
                    ParseTextProtoOrDie<ValidationStatus>(R"pb(
                      code: "assertion.dataHash.match"
                    )pb"))));
  }

  // Writes a manifest store into a copy of `image` using `writer`.
  static absl::StatusOr<std::string> WriteCopy(
      const JpegWriter& writer, GenerateManifestStoreRequest request,
      absl::string_view image,
      JpegWriter::OutputMetadata* output_metadata = nullptr) {
    riegeli::StringReader source(image);
    std::string result;
    riegeli::StringWriter destination(&result);
    absl::Status status = writer.Write(std::move(request), &source,
                                       &destination, output_metadata);
    if (!status.ok()) return status;
    if (!destination.Close()) return destination.status();
    return result;
  }

  std::unique_ptr<ManifestStoreGenerator> generator_;
  std::unique_ptr<JpegWriter> writer_;
  std::unique_ptr<AssetValidator> validator_;
};

TEST_F(JpegWriterTest, Write) {
  std::string image = CreateJpegImage();
  JpegWriter::OutputMetadata output_metadata;
  absl::StatusOr<std::string> result =
      WriteCopy(*writer_, CreateRequest(), image, &output_metadata);
  ABSL_ASSERT_OK(result);
  EXPECT_TRUE(output_metadata.timestamp_included);
  EXPECT_GT(result->size(), image.size());
  ExpectValid(*result);

  absl::StatusOr<ValidationStatusSet> validation = Validate(*result);
  ABSL_ASSERT_OK(validation);
  EXPECT_THAT(validation->informationals(),
              Not(Contains(PartiallyEqualsProto(
                  ParseTextProtoOrDie<ValidationStatus>(R"pb(
                    code: "assertion.dataHash.additionalExclusionsPresent"
                  )pb")))));
}

TEST_F(JpegWriterTest, WriteInsertsManifestStoreBeforeFirstNonAppSegment) {
  FakeManifestStoreGenerator generator(CreateFakeManifestStore());
  JpegWriter writer(&generator);
  std::string image = CreateJpegImage();
  size_t dqt_offset = image.find("\xff\xdb");
  ASSERT_NE(dqt_offset, std::string::npos);

  absl::StatusOr<std::string> result =
      WriteCopy(writer, CreateRequest(), image);
  ABSL_ASSERT_OK(result);

  // Bytes before the insertion point are unchanged.
  EXPECT_THAT(*result, StartsWith(image.substr(0, dqt_offset)));
  // An APP11 segment containing the manifest store is inserted.
  EXPECT_EQ(result->substr(dqt_offset, 2), "\xff\xeb");
  EXPECT_THAT(*result, HasSubstr(generator.manifest_store()));
  // Bytes after the insertion point are unchanged.
  EXPECT_EQ(result->substr(result->size() - (image.size() - dqt_offset)),
            image.substr(dqt_offset));
}

TEST_F(JpegWriterTest, WriteWithoutOutputMetadata) {
  absl::StatusOr<std::string> result =
      WriteCopy(*writer_, CreateRequest(), CreateJpegImage());
  ABSL_ASSERT_OK(result);
  ExpectValid(*result);
}

TEST_F(JpegWriterTest, WriteWithoutTimestamp) {
  auto generator =
      CreateNonProdManifestStoreGenerator({.disable_timestamping = true});
  ABSL_ASSERT_OK(generator);
  JpegWriter writer(generator->get());

  JpegWriter::OutputMetadata output_metadata;
  absl::StatusOr<std::string> result =
      WriteCopy(writer, CreateRequest(), CreateJpegImage(), &output_metadata);
  ABSL_ASSERT_OK(result);
  EXPECT_FALSE(output_metadata.timestamp_included);
  ExpectValid(*result);
}

TEST_F(JpegWriterTest, WriteInPlace) {
  std::string image = CreateJpegImage();
  const size_t original_size = image.size();
  riegeli::StringWriter<> asset(
      &image, riegeli::StringWriterBase::Options().set_append(true));
  ABSL_ASSERT_OK(asset.status());

  JpegWriter::OutputMetadata output_metadata;
  ABSL_ASSERT_OK(writer_->Write(CreateRequest(), &asset, &output_metadata));
  ASSERT_TRUE(asset.Close());
  EXPECT_TRUE(output_metadata.timestamp_included);
  EXPECT_GT(image.size(), original_size);
  ExpectValid(image);
}

TEST_F(JpegWriterTest, WriteInPlaceWithoutOutputMetadata) {
  std::string image = CreateJpegImage();
  riegeli::StringWriter<> asset(
      &image, riegeli::StringWriterBase::Options().set_append(true));
  ABSL_ASSERT_OK(asset.status());

  ABSL_ASSERT_OK(writer_->Write(CreateRequest(), &asset));
  ASSERT_TRUE(asset.Close());
  ExpectValid(image);
}

TEST_F(JpegWriterTest, WriteInPlaceFailsWhenRandomAccessNotSupported) {
  class NonRandomAccessWriter : public riegeli::StringWriter<> {
   public:
    using StringWriter::StringWriter;
    bool SupportsRandomAccess() override { return false; }
  };
  std::string image = CreateJpegImage();
  NonRandomAccessWriter asset(&image);
  EXPECT_THAT(writer_->Write(CreateRequest(), &asset),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("asset does not support random access")));
}

TEST_F(JpegWriterTest, WriteInPlaceFailsWhenReadModeNotSupported) {
  class NonReadModeWriter : public riegeli::StringWriter<> {
   public:
    using StringWriter::StringWriter;
    bool SupportsReadMode() override { return false; }
  };
  std::string image = CreateJpegImage();
  NonReadModeWriter asset(
      &image, riegeli::StringWriterBase::Options().set_append(true));
  EXPECT_THAT(writer_->Write(CreateRequest(), &asset),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("asset does not support read mode")));
}

TEST_F(JpegWriterTest, WriteWithHardBindingFails) {
  GenerateManifestStoreRequest request = CreateRequest();
  request.mutable_hard_binding();
  EXPECT_THAT(WriteCopy(*writer_, request, CreateJpegImage()),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("must not include `hard_binding`")));
}

TEST_F(JpegWriterTest, WriteInPlaceWithHardBindingFails) {
  GenerateManifestStoreRequest request = CreateRequest();
  request.mutable_hard_binding();
  std::string image = CreateJpegImage();
  const std::string original = image;
  riegeli::StringWriter<> asset(
      &image, riegeli::StringWriterBase::Options().set_append(true));
  EXPECT_THAT(writer_->Write(request, &asset),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("must not include `hard_binding`")));
  ASSERT_TRUE(asset.Close());
  EXPECT_EQ(image, original);
}

TEST_F(JpegWriterTest, WriteWithMultiAssetHash) {
  GenerateManifestStoreRequest request = CreateRequest();
  request.mutable_options()->set_generate_multi_asset_hash(true);
  absl::StatusOr<std::string> result =
      WriteCopy(*writer_, request, CreateJpegImage());
  ABSL_ASSERT_OK(result);
  ExpectValid(*result);
}

TEST_F(JpegWriterTest, WriteFailsWhenNoInsertionPointFound) {
  EXPECT_THAT(
      WriteCopy(*writer_, CreateRequest(),
                absl::string_view("\xff\xd8\xff\xe0\x00\x02", 6)),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("No valid C2PA insertion point found in JPEG")));
}

TEST_F(JpegWriterTest, WriteFailsWhenManifestStoreAlreadyExists) {
  absl::StatusOr<std::string> result =
      WriteCopy(*writer_, CreateRequest(), CreateJpegImage());
  ABSL_ASSERT_OK(result);

  EXPECT_THAT(WriteCopy(*writer_, CreateRequest(), *result),
              StatusIs(absl::StatusCode::kAlreadyExists,
                       HasSubstr("C2PA chunk already exists")));
}

TEST_F(JpegWriterTest, ModifyingHashedBytesInvalidatesAsset) {
  absl::StatusOr<std::string> result =
      WriteCopy(*writer_, CreateRequest(), CreateJpegImage());
  ABSL_ASSERT_OK(result);

  (*result)[ExifOffset(*result) + kExifPayload.size() - 1] ^= 0xff;
  absl::StatusOr<ValidationStatusSet> validation = Validate(*result);
  ABSL_ASSERT_OK(validation);
  EXPECT_THAT(
      validation->failures(),
      Contains(PartiallyEqualsProto(ParseTextProtoOrDie<ValidationStatus>(R"pb(
        code: "assertion.dataHash.mismatch"
      )pb"))));
}

TEST_F(JpegWriterTest, WriteAsync) {
  std::string image = CreateJpegImage();
  riegeli::StringReader source(image);
  std::string result;
  riegeli::StringWriter destination(&result);

  absl::Notification done;
  absl::Status write_status;
  JpegWriter::OutputMetadata output_metadata;
  writer_->Write(CreateRequest(), &source, &destination, &output_metadata,
                 AsyncContext(), [&](absl::Status status) {
                   write_status = std::move(status);
                   done.Notify();
                 });
  done.WaitForNotification();
  ABSL_ASSERT_OK(write_status);
  ASSERT_TRUE(destination.Close());
  EXPECT_TRUE(output_metadata.timestamp_included);
  ExpectValid(result);
}

TEST_F(JpegWriterTest, WriteInPlaceAsync) {
  std::string image = CreateJpegImage();
  riegeli::StringWriter<> asset(
      &image, riegeli::StringWriterBase::Options().set_append(true));

  absl::Notification done;
  absl::Status write_status;
  writer_->Write(CreateRequest(), &asset, /*output_metadata=*/nullptr,
                 AsyncContext(), [&](absl::Status status) {
                   write_status = std::move(status);
                   done.Notify();
                 });
  done.WaitForNotification();
  ABSL_ASSERT_OK(write_status);
  ASSERT_TRUE(asset.Close());
  ExpectValid(image);
}

TEST_F(JpegWriterTest, WriteAsyncReportsErrorThroughCallback) {
  GenerateManifestStoreRequest request = CreateRequest();
  request.mutable_hard_binding();
  std::string image = CreateJpegImage();
  riegeli::StringReader source(image);
  std::string result;
  riegeli::StringWriter destination(&result);

  absl::Notification done;
  absl::Status write_status;
  writer_->Write(request, &source, &destination, /*output_metadata=*/nullptr,
                 AsyncContext(), [&](absl::Status status) {
                   write_status = std::move(status);
                   done.Notify();
                 });
  done.WaitForNotification();
  EXPECT_THAT(write_status, StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST_F(JpegWriterTest, ExclusionProcessorExcludesBytesFromHardBinding) {
  std::vector<std::string> visited_segments;
  JpegWriter writer(
      generator_.get(),
      {.exclusion_processor = [&visited_segments](
                                  riegeli::Reader&, const JpegSegment& segment,
                                  const GenerateManifestStoreRequest& request)
           -> absl::StatusOr<std::vector<ByteRange>> {
        EXPECT_EQ(request.actions().created().action_metadata().description(),
                  "test only");
        visited_segments.push_back(segment.marker_label);
        if (segment.marker_label != "APP1") return std::vector<ByteRange>();
        return std::vector<ByteRange>{{.offset = segment.payload_offset,
                                       .length = segment.payload_length}};
      }});

  absl::StatusOr<std::string> result =
      WriteCopy(writer, CreateRequest(), CreateJpegImage());
  ABSL_ASSERT_OK(result);
  EXPECT_THAT(visited_segments, Contains("APP0"));
  EXPECT_THAT(visited_segments, Contains("APP1"));
  EXPECT_THAT(visited_segments, Contains("DQT"));
  ExpectValid(*result);

  absl::StatusOr<ValidationStatusSet> validation = Validate(*result);
  ABSL_ASSERT_OK(validation);
  EXPECT_THAT(
      validation->informationals(),
      Contains(PartiallyEqualsProto(ParseTextProtoOrDie<ValidationStatus>(R"pb(
        code: "assertion.dataHash.additionalExclusionsPresent"
      )pb"))));

  // Modifying excluded bytes does not invalidate the asset.
  (*result)[ExifOffset(*result) + kExifPayload.size() - 1] ^= 0xff;
  ExpectValid(*result);
}

TEST_F(JpegWriterTest, ExclusionProcessorErrorIsPropagated) {
  JpegWriter writer(
      generator_.get(),
      {.exclusion_processor = [](riegeli::Reader&, const JpegSegment&,
                                 const GenerateManifestStoreRequest&)
           -> absl::StatusOr<std::vector<ByteRange>> {
        return absl::DataLossError("exclusion failure");
      }});

  EXPECT_THAT(WriteCopy(writer, CreateRequest(), CreateJpegImage()),
              StatusIs(absl::StatusCode::kDataLoss, "exclusion failure"));
}

TEST_F(JpegWriterTest, ExclusionProcessorRangeOutsideSegmentFails) {
  JpegWriter writer(
      generator_.get(),
      {.exclusion_processor = [](riegeli::Reader&, const JpegSegment& segment,
                                 const GenerateManifestStoreRequest&)
           -> absl::StatusOr<std::vector<ByteRange>> {
        return std::vector<ByteRange>{
            {.offset = segment.offset, .length = segment.length + 1}};
      }});

  EXPECT_THAT(WriteCopy(writer, CreateRequest(), CreateJpegImage()),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Invalid or overlapping exclusion range")));
}

TEST_F(JpegWriterTest, GeneratorErrorIsPropagated) {
  FakeManifestStoreGenerator generator;
  generator.set_status(absl::UnavailableError("generator failure"));
  JpegWriter writer(&generator);

  EXPECT_THAT(WriteCopy(writer, CreateRequest(), CreateJpegImage()),
              StatusIs(absl::StatusCode::kUnavailable, "generator failure"));
}

TEST_F(JpegWriterTest, InPlaceGeneratorErrorLeavesAssetUnchanged) {
  FakeManifestStoreGenerator generator;
  generator.set_status(absl::UnavailableError("generator failure"));
  JpegWriter writer(&generator);
  std::string image = CreateJpegImage();
  const std::string original = image;
  riegeli::StringWriter<> asset(
      &image, riegeli::StringWriterBase::Options().set_append(true));

  EXPECT_THAT(writer.Write(CreateRequest(), &asset),
              StatusIs(absl::StatusCode::kUnavailable, "generator failure"));
  ASSERT_TRUE(asset.Close());
  EXPECT_EQ(image, original);
}

TEST_F(JpegWriterTest, WriteFailsWithEmptyManifestStoreTemplate) {
  FakeManifestStoreGenerator generator;
  generator.mutable_manifest_store_template()->set_manifest_store_size(0);
  JpegWriter writer(&generator);

  EXPECT_THAT(WriteCopy(writer, CreateRequest(), CreateJpegImage()),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("invalid manifest store template size: 0")));
}

TEST_F(JpegWriterTest, WriteFailsWithTooLargeManifestStoreTemplate) {
  FakeManifestStoreGenerator generator;
  generator.mutable_manifest_store_template()->set_manifest_store_size(
      100 * 1024 * 1024 + 1);
  JpegWriter writer(&generator);

  EXPECT_THAT(WriteCopy(writer, CreateRequest(), CreateJpegImage()),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("invalid manifest store template size")));
}

TEST_F(JpegWriterTest, OutputMetadataReflectsFinalizeResponse) {
  FakeManifestStoreGenerator generator(CreateFakeManifestStore());
  JpegWriter writer(&generator);

  JpegWriter::OutputMetadata output_metadata;
  generator.mutable_finalize_manifest_store_response()->set_is_timestamped(
      true);
  ABSL_ASSERT_OK(
      WriteCopy(writer, CreateRequest(), CreateJpegImage(), &output_metadata));
  EXPECT_TRUE(output_metadata.timestamp_included);

  output_metadata.timestamp_included = true;
  generator.mutable_finalize_manifest_store_response()->set_is_timestamped(
      false);
  ABSL_ASSERT_OK(
      WriteCopy(writer, CreateRequest(), CreateJpegImage(), &output_metadata));
  EXPECT_FALSE(output_metadata.timestamp_included);
}

TEST_F(JpegWriterTest, LargeManifestStoreIsSplitAcrossApp11Segments) {
  // A manifest store larger than a single APP11 segment (64 KiB).
  FakeManifestStoreGenerator generator(CreateFakeManifestStore(200 * 1024));
  JpegWriter writer(&generator);

  absl::StatusOr<std::string> result =
      WriteCopy(writer, CreateRequest(), CreateJpegImage());
  ABSL_ASSERT_OK(result);

  std::vector<size_t> app11_offsets;
  for (size_t pos = result->find("\xff\xeb"); pos != std::string::npos;
       pos = result->find("\xff\xeb", pos + 1)) {
    app11_offsets.push_back(pos);
  }
  EXPECT_THAT(app11_offsets, SizeIs(Gt(3)));
}

}  // namespace
}  // namespace credentio
