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

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

#include "absl/log/absl_check.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/string_view.h"
#include "formats/byte_range.h"
#include "formats/pdf/extractor.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/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 "validator/asset_validator.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::AllOf;
using ::testing::Field;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::IsEmpty;
using ::testing::Optional;

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
)";

class PdfWriterTest : public ::testing::Test {
 protected:
  void SetUp() override {
    auto generator = CreateNonProdManifestStoreGenerator({});
    ABSL_CHECK_OK(generator);
    generator_ = std::move(*generator);
    writer_ = std::make_unique<PdfWriter>(generator_.get());
    auto validator = CreateNonProdValidator({});
    ABSL_CHECK_OK(validator);
    validator_ = std::move(*validator);
  }
  std::unique_ptr<ManifestStoreGenerator> generator_;
  std::unique_ptr<PdfWriter> writer_;
  std::unique_ptr<AssetValidator> validator_;
};

TEST_F(PdfWriterTest, Write) {
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");
  riegeli::StringReader source(kTestPdfContent);
  ABSL_ASSERT_OK(source.status());
  std::string result;
  riegeli::StringWriter destination(&result);
  ABSL_ASSERT_OK(destination.status());
  ABSL_ASSERT_OK(writer_->Write(request, &source, &destination));
  ASSERT_TRUE(source.Close());
  ASSERT_TRUE(destination.Close());

  riegeli::StringReader result_reader(result);
  ABSL_ASSERT_OK(result_reader.status());

  EXPECT_THAT(PdfExtractor().ExtractManifestStoreLocation(result_reader, {}),
              IsOkAndHolds(Optional(AllOf(Field(&ByteRange::offset, Gt(0)),
                                          Field(&ByteRange::length, Gt(0))))));

  ASSERT_TRUE(result_reader.Seek(0));
  auto validation_result =
      validator_->Validate(result_reader, "application/pdf");
  ABSL_ASSERT_OK(validation_result);
  EXPECT_THAT(
      (*validation_result)->proto().active_manifest().validation().failures(),
      IsEmpty());
}

TEST_F(PdfWriterTest, WriteTwiceFails) {
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");

  riegeli::StringReader source1(kTestPdfContent);
  ABSL_ASSERT_OK(source1.status());
  std::string result1;
  riegeli::StringWriter destination1(&result1);
  ABSL_ASSERT_OK(destination1.status());
  ABSL_ASSERT_OK(writer_->Write(request, &source1, &destination1));
  ASSERT_TRUE(source1.Close());
  ASSERT_TRUE(destination1.Close());

  riegeli::StringReader source2(result1);
  ABSL_ASSERT_OK(source2.status());
  std::string result2;
  riegeli::StringWriter destination2(&result2);
  ABSL_ASSERT_OK(destination2.status());
  EXPECT_THAT(
      writer_->Write(request, &source2, &destination2),
      StatusIs(absl::StatusCode::kAlreadyExists, HasSubstr("already exists")));
}

TEST_F(PdfWriterTest, WriteWithHardBindingFails) {
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");
  request.mutable_hard_binding();

  riegeli::StringReader source(kTestPdfContent);
  ABSL_ASSERT_OK(source.status());
  std::string result;
  riegeli::StringWriter destination(&result);
  ABSL_ASSERT_OK(destination.status());
  EXPECT_THAT(writer_->Write(request, &source, &destination),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("must not include `hard_binding`")));
}

class PdfWriterInvalidSizeTest : public ::testing::TestWithParam<int64_t> {};

TEST_P(PdfWriterInvalidSizeTest, RejectsInvalidManifestStoreSize) {
  int64_t invalid_size = GetParam();
  FakeManifestStoreGenerator generator;
  generator.mutable_manifest_store_template()->set_manifest_store_size(
      invalid_size);
  PdfWriter writer(&generator);
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");
  riegeli::StringReader source(kTestPdfContent);
  ABSL_ASSERT_OK(source.status());
  std::string result;
  riegeli::StringWriter destination(&result);
  ABSL_ASSERT_OK(destination.status());

  EXPECT_THAT(writer.Write(request, &source, &destination),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("invalid manifest store template size:")));
}

INSTANTIATE_TEST_SUITE_P(PdfWriterInvalidSizeTests, PdfWriterInvalidSizeTest,
                         ::testing::Values(-5, 0, 10LL * 1024 * 1024 + 1));

TEST(PdfWriterMaxSizeTest, LargestManifestStoreCanBeReadBack) {
  constexpr int64_t kMaxManifestStoreSize = 10 * 1024 * 1024;
  FakeManifestStoreGenerator generator(std::string(kMaxManifestStoreSize, 'x'));
  PdfWriter writer(&generator);
  GenerateManifestStoreRequest request;
  request.mutable_actions()
      ->mutable_created()
      ->mutable_action_metadata()
      ->set_description("test only");
  riegeli::StringReader source(kTestPdfContent);
  ABSL_ASSERT_OK(source.status());
  std::string result;
  riegeli::StringWriter destination(&result);
  ABSL_ASSERT_OK(destination.status());
  ABSL_ASSERT_OK(writer.Write(request, &source, &destination));
  ASSERT_TRUE(destination.Close());

  // The location covers the whole stream object, not just its data.
  riegeli::StringReader result_reader(result);
  EXPECT_THAT(PdfExtractor().ExtractManifestStoreLocation(result_reader, {}),
              IsOkAndHolds(Optional(
                  Field(&ByteRange::length,
                        Gt(static_cast<uint64_t>(kMaxManifestStoreSize))))));
}

}  // namespace
}  // namespace credentio
