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

#include <cstdint>
#include <string>

#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/str_cat.h"
#include "absl/strings/string_view.h"
#include "crypto/algorithms.h"
#include "formats/pdf/constants.h"
#include "formats/pdf/extractor.h"
#include "formats/pdf/objects.h"
#include "formats/pdf/reader.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "proto/data_hash_assertion.pb.h"
#include "proto/generator.pb.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"
#include "testing/nonprod_generator.h"

namespace credentio {
namespace {

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

constexpr absl::string_view kTestPdfContent = R"(%PDF-1.7
%%%%%
1 0 obj
/test_name
endobj
2 0 obj
123.456
endobj
3 0 obj
<</Type /Catalog>>
endobj
xref
0 4
0000000000 65535 f 
0000000015 00000 n 
0000000041 00000 n 
0000000064 00000 n 
trailer
<</Root 3 0 R /Size 4>>
startxref
98
%%EOF
)";

constexpr absl::string_view kTestPdfContentWithDirectNamesDict = R"(%PDF-1.7
%%%%%
1 0 obj
/test_name
endobj
2 0 obj
123.456
endobj
3 0 obj
<</Names <<>> /Type /Catalog>>
endobj
xref
0 4
0000000000 65535 f 
0000000015 00000 n 
0000000041 00000 n 
0000000064 00000 n 
trailer
<</Root 3 0 R /Size 4>>
startxref
110
%%EOF
)";

constexpr absl::string_view kTestPdfContentWithFreeObjectEntries = R"(%PDF-1.7
%%%%%
1 0 obj
/test_name
endobj
3 0 obj
123.456
endobj
5 0 obj
<</Type /Catalog>>
endobj
xref
0 6
0000000002 65535 f 
0000000015 00000 n 
0000000004 00000 f 
0000000041 00000 n 
0000000000 00000 f 
0000000064 00000 n 
trailer
<</Root 5 0 R /Size 6>>
startxref
98
%%EOF
)";

absl::StatusOr<std::string> CreateManifestStore() {
  ABSL_ASSIGN_OR_RETURN(auto generator,
                        CreateNonProdManifestStoreGenerator({}));
  GenerateManifestStoreRequest request;
  DataHashAssertion* data_hash =
      request.mutable_hard_binding()->mutable_data_hash();
  data_hash->set_alg(absl::StrCat(HashAlgorithm::kSha256));
  data_hash->set_hash("data_hash");
  request.mutable_actions()->mutable_created();
  ABSL_ASSIGN_OR_RETURN(auto response,
                        generator->GenerateManifestStore(request));
  return std::string(response.manifest_store());
}

TEST(PdfRewriterTest, RewriteForEmbedding) {
  riegeli::StringReader<> input(kTestPdfContent);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(PdfEmbedder().RewriteForEmbedding(
                  input, /*estimated_manifest_store_size=*/100, output),
              IsOk());
  ASSERT_TRUE(output.Close());

  riegeli::StringReader<> output_reader(output_s);
  EXPECT_THAT(PdfExtractor().ExtractManifestStore(output_reader),
              IsOkAndHolds(std::string(100, '\0')));
}

TEST(PdfRewriterTest, RewriteForEmbeddingMovesDirectNamesDict) {
  riegeli::StringReader<> input(kTestPdfContentWithDirectNamesDict);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(PdfEmbedder().RewriteForEmbedding(
                  input, /*estimated_manifest_store_size=*/100, output),
              IsOk());
  ASSERT_TRUE(output.Close());

  riegeli::StringReader<> output_reader(output_s);
  auto reader = PdfReader::Create(&output_reader);
  ABSL_ASSERT_OK(reader);
  auto trailer_dict = (*reader)->file_trailer_dictionary();
  auto doc_catalog_dict_obj = (*reader)->GetObject(3, 0);
  ABSL_ASSERT_OK(doc_catalog_dict_obj);
  auto doc_catalog_dict =
      Object::As<Object::Dictionary>(doc_catalog_dict_obj->object);
  ABSL_ASSERT_OK(doc_catalog_dict);

  // Verify that the catalog names dictionary is moved into an indirect object
  // and referenced from the document catalog dictionary.
  EXPECT_THAT(
      (*reader)->GetObject(4, 0),
      IsOkAndHolds(IndirectObject{
          .object_number = 4,
          .generation_number = 0,
          .object = Object{
              .value = Object::Dictionary{
                  .entries = {{"EmbeddedFiles",
                               Object{.value = Object::IndirectReference{
                                          .object_number = 7,
                                          .generation_number = 0}}}}}}}));
  EXPECT_THAT(doc_catalog_dict->entries.at("Names"),
              (Object{.value = Object::IndirectReference{
                          .object_number = 4, .generation_number = 0}}));
}

TEST(PdfRewriterTest, RewriteForEmbeddingRespectsFreeObjectEntries) {
  riegeli::StringReader<> input(kTestPdfContentWithFreeObjectEntries);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(PdfEmbedder().RewriteForEmbedding(
                  input, /*estimated_manifest_store_size=*/100, output),
              IsOk());
  ASSERT_TRUE(output.Close());

  riegeli::StringReader<> output_reader(output_s);
  auto reader = PdfReader::Create(&output_reader);
  ABSL_ASSERT_OK(reader);
  EXPECT_THAT((*reader)->free_entries(),
              ElementsAre(Object::IndirectReference{.object_number = 0,
                                                    .generation_number = 65535},
                          Object::IndirectReference{.object_number = 2,
                                                    .generation_number = 0},
                          Object::IndirectReference{.object_number = 4,
                                                    .generation_number = 0}));
}

TEST(PdfRewriterTest, RewriteForEmbeddingFailsIfC2paManifestAlreadyExists) {
  // Prepare a C2PA-embeddable PDF.
  riegeli::StringReader<> input(kTestPdfContent);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(PdfEmbedder().RewriteForEmbedding(
                  input, /*estimated_manifest_store_size=*/100, output),
              IsOk());
  ASSERT_TRUE(output.Close());

  // Rewrite the PDF again, it should fail.
  riegeli::StringReader<> output_reader(output_s);
  std::string output_s2;
  riegeli::StringWriter<> output2(&output_s2);
  EXPECT_THAT(
      PdfEmbedder().RewriteForEmbedding(
          output_reader, /*estimated_manifest_store_size=*/100, output2),
      StatusIs(absl::StatusCode::kAlreadyExists,
               HasSubstr("C2PA manifest store already exists")));
}

TEST(PdfRewriterTest, Embed) {
  auto manifest_store = CreateManifestStore();
  ABSL_ASSERT_OK(manifest_store);

  // Prepare a C2PA-embeddable PDF.
  riegeli::StringReader<> input(kTestPdfContent);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  absl::StatusOr<int64_t> manifest_store_offset =
      PdfEmbedder().RewriteForEmbedding(input, manifest_store->size(), output);
  ABSL_ASSERT_OK(manifest_store_offset);
  ASSERT_TRUE(output.Close());

  // Embed the manifest store.
  absl::Cord embeddable_asset(output_s);
  EXPECT_THAT(PdfEmbedder().Embed(*manifest_store, *manifest_store_offset,
                                  embeddable_asset),
              IsOk());

  riegeli::StringReader<> output_reader(embeddable_asset.Flatten());
  EXPECT_THAT(PdfExtractor().ExtractManifestStore(output_reader),
              IsOkAndHolds(*manifest_store));
}

TEST(PdfRewriterTest, RewriteForEmbeddingCorrectLayout) {
  riegeli::StringReader<> input(kTestPdfContent);
  std::string output_s;
  riegeli::StringWriter<> output(&output_s);
  EXPECT_THAT(PdfEmbedder().RewriteForEmbedding(
                  input, /*estimated_manifest_store_size=*/100, output),
              IsOk());
  ASSERT_TRUE(output.Close());

  riegeli::StringReader<> output_reader(output_s);
  auto reader = PdfReader::Create(&output_reader);
  ABSL_ASSERT_OK(reader);

  // The catalog should have /AF pointing to the file spec.
  auto doc_catalog_dict_obj = (*reader)->GetObject(3, 0);
  ABSL_ASSERT_OK(doc_catalog_dict_obj);
  auto doc_catalog_dict =
      Object::As<Object::Dictionary>(doc_catalog_dict_obj->object);
  ABSL_ASSERT_OK(doc_catalog_dict);
  auto af_array =
      FindObjectInDictionary<Object::Array>(*doc_catalog_dict, kPdfAfKey);
  ABSL_ASSERT_OK(af_array);
  ASSERT_EQ(af_array->objects.size(), 1);
  auto file_spec_ref =
      Object::As<Object::IndirectReference>(af_array->objects[0]);
  ABSL_ASSERT_OK(file_spec_ref);

  // Inspect the file spec object.
  auto file_spec_obj = (*reader)->GetObject(file_spec_ref->object_number,
                                            file_spec_ref->generation_number);
  ABSL_ASSERT_OK(file_spec_obj);
  auto file_spec_dict = Object::As<Object::Dictionary>(file_spec_obj->object);
  ABSL_ASSERT_OK(file_spec_dict);

  // Subtype should NOT be in file spec dictionary.
  EXPECT_THAT(
      FindObjectInDictionary<Object::Name>(*file_spec_dict, kPdfSubtypeKey),
      StatusIs(absl::StatusCode::kNotFound));

  // AFRelationship should be C2PA_Manifest.
  EXPECT_THAT(FindObjectInDictionary<Object::Name>(*file_spec_dict,
                                                   kPdfAfRelationshipKey),
              IsOkAndHolds(Object::Name{
                  .value = std::string(kPdfC2paManifestAfRelationship)}));

  // Get the embedded file stream ref.
  auto ef_dict =
      FindObjectInDictionary<Object::Dictionary>(*file_spec_dict, kPdfEfKey);
  ABSL_ASSERT_OK(ef_dict);
  auto stream_ref =
      FindObjectInDictionary<Object::IndirectReference>(*ef_dict, kPdfFKey);
  ABSL_ASSERT_OK(stream_ref);

  // Inspect the stream object.
  auto stream_obj = (*reader)->GetObject(stream_ref->object_number,
                                         stream_ref->generation_number);
  ABSL_ASSERT_OK(stream_obj);
  ASSERT_TRUE(stream_obj->stream_dictionary.has_value());
  const auto& stream_dict = *stream_obj->stream_dictionary;

  // Subtype should be in stream dictionary.
  EXPECT_THAT(FindObjectInDictionary<Object::Name>(stream_dict, kPdfSubtypeKey),
              IsOkAndHolds(Object::Name{
                  .value = std::string(kPdfC2paManifestMimeType)}));

  // Params should be in stream dictionary.
  auto params_dict =
      FindObjectInDictionary<Object::Dictionary>(stream_dict, kPdfParamsKey);
  ABSL_ASSERT_OK(params_dict);
  // Params should contain Size.
  EXPECT_THAT(
      FindObjectInDictionary<Object::Integer>(*params_dict, kPdfSizeKey),
      IsOkAndHolds(Object::Integer{.value = 100}));

  // Params should contain ModDate.
  auto mod_date_obj = FindObjectInDictionary<Object::LiteralString>(
      *params_dict, kPdfModDateKey);
  ABSL_ASSERT_OK(mod_date_obj);
  EXPECT_THAT(mod_date_obj->raw_value,
              testing::MatchesRegex("D:[0-9]{14}[+]00'00'"));
}

}  // namespace
}  // namespace credentio
