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

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

#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/string_view.h"
#include "formats/byte_range.h"
#include "formats/zip/constants.h"
#include "formats/zip/extractor.h"
#include "formats/zip/reader.h"
#include "formats/zip/zlib_util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/string_reader.h"
#include "riegeli/bytes/string_writer.h"
#include "testing/test_file_utils.h"

namespace credentio {
namespace {

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

absl::StatusOr<std::vector<ZipReader::FileEntry>> GetFileEntries(
    riegeli::Reader& input) {
  ABSL_ASSIGN_OR_RETURN(auto reader, ZipReader::Create(&input));
  std::vector<ZipReader::FileEntry> file_entries;
  while (reader->HasNext()) {
    ABSL_ASSIGN_OR_RETURN(ZipReader::FileEntry entry, reader->Next());
    file_entries.push_back(entry);
  }
  return file_entries;
}

absl::StatusOr<std::string> GetContentTypesStream(riegeli::Reader& input) {
  ABSL_ASSIGN_OR_RETURN(auto reader, ZipReader::Create(&input));
  while (reader->HasNext()) {
    ABSL_ASSIGN_OR_RETURN(ZipReader::FileEntry entry, reader->Next());
    if (entry.file_name == kOoxmlContentTypesFileName) {
      if (!input.Seek(entry.file_range.offset)) {
        return input.StatusOrAnnotate(absl::DataLossError("failed to seek"));
      }
      std::string content;
      if (!input.Read(entry.file_range.length, content)) {
        return input.StatusOrAnnotate(absl::DataLossError("failed to read"));
      }
      ABSL_ASSIGN_OR_RETURN(std::string uncompressed, Uncompress(content));
      return uncompressed;
    }
  }
  return absl::NotFoundError("Content types stream not found.");
}

class ZipEmbedderTest : public testing::Test {
 protected:
  void InitWithZipFile(absl::string_view file_name,
                       int64_t manifest_store_size) {
    auto source = credentio_testing::GetFileReader(file_name);
    ABSL_ASSERT_OK(source);
    source_ = *std::move(source);
    auto file_entries = GetFileEntries(*source_);
    ABSL_ASSERT_OK(file_entries);
    file_entries_ = *std::move(file_entries);

    destination_ = std::make_unique<riegeli::StringWriter<>>(&output_s_);
    manifest_store_size_ = manifest_store_size;
  }

  std::string zip_file_contents_;
  std::unique_ptr<riegeli::Reader> source_;
  std::vector<ZipReader::FileEntry> file_entries_;
  std::string output_s_;
  std::unique_ptr<riegeli::StringWriter<>> destination_;
  int64_t manifest_store_size_;
};

TEST_F(ZipEmbedderTest, CopyAndAllocateFailsIfManifestStoreAlreadyExists) {
  InitWithZipFile(
      "credentio/formats/zip/testing/"
      "asset_fake_c2pa.zip",
      /*manifest_store_size=*/100);

  EXPECT_THAT(
      ZipEmbedder().CopyAndAllocate(source_.get(), file_entries_,
                                    manifest_store_size_, destination_.get()),
      StatusIs(absl::StatusCode::kAlreadyExists,
               HasSubstr("Manifest store already exists.")));
}

TEST_F(ZipEmbedderTest, CopyAndAllocateFailsIfNoContentTypesStream) {
  InitWithZipFile("credentio/formats/zip/testing/asset_no_c2pa.zip",
                  /*manifest_store_size=*/100);

  EXPECT_THAT(
      ZipEmbedder().CopyAndAllocate(source_.get(), file_entries_,
                                    manifest_store_size_, destination_.get()),
      StatusIs(absl::StatusCode::kNotFound,
               HasSubstr("Content types stream not found.")));
}

TEST_F(ZipEmbedderTest, CopyAndAllocate) {
  InitWithZipFile("credentio/formats/zip/testing/no_c2pa_032_asset.pptx",
                  /*manifest_store_size=*/100);

  auto copy_and_allocate_result = ZipEmbedder().CopyAndAllocate(
      source_.get(), file_entries_, manifest_store_size_, destination_.get());
  ABSL_ASSERT_OK(copy_and_allocate_result);
  ASSERT_TRUE(destination_->Close());

  riegeli::StringReader<absl::string_view> output_reader(output_s_);

  EXPECT_THAT(ZipExtractor().ExtractManifestStore(output_reader),
              IsOkAndHolds(std::string(100, '\0')));
  ASSERT_TRUE(output_reader.Seek(0));
  EXPECT_THAT(ZipExtractor().ExtractManifestStoreLocation(output_reader, {}),
              IsOkAndHolds(ByteRange{
                  .offset = copy_and_allocate_result->manifest_store_offset,
                  .length = 100,
              }));
  ASSERT_TRUE(output_reader.Seek(0));
  auto content_types_stream = GetContentTypesStream(output_reader);
  ABSL_ASSERT_OK(content_types_stream);
  EXPECT_THAT(
      *content_types_stream,
      HasSubstr(
          R"(<Override ContentType="application/c2pa" PartName="/META-INF/content_credential.c2pa"/>)"));
}

TEST_F(ZipEmbedderTest, Embed) {
  std::string manifest_store = "c2pa manifest store";
  InitWithZipFile("credentio/formats/zip/testing/no_c2pa_032_asset.pptx",
                  manifest_store.size());

  auto copy_and_allocate_result = ZipEmbedder().CopyAndAllocate(
      source_.get(), file_entries_, manifest_store_size_, destination_.get());
  ABSL_ASSERT_OK(copy_and_allocate_result);

  EXPECT_THAT(ZipEmbedder().Embed(manifest_store, *copy_and_allocate_result,
                                  destination_.get()),
              IsOk());
  ASSERT_TRUE(destination_->Close());

  riegeli::StringReader output_reader(&output_s_);

  EXPECT_THAT(ZipExtractor().ExtractManifestStore(output_reader),
              IsOkAndHolds(manifest_store));
}

TEST_F(ZipEmbedderTest, CopyAndAllocateFailsWithDuplicateEntries) {
  InitWithZipFile("credentio/formats/zip/testing/no_c2pa_032_asset.pptx", 100);
  ASSERT_GE(file_entries_.size(), 1);

  std::vector<ZipReader::FileEntry> duplicate_entries = file_entries_;
  duplicate_entries.push_back(file_entries_[0]);

  EXPECT_THAT(
      ZipEmbedder().CopyAndAllocate(source_.get(), duplicate_entries,
                                    manifest_store_size_, destination_.get()),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("Overlapping or duplicate ZIP entries detected")));
}

TEST_F(ZipEmbedderTest, CopyAndAllocatePreservesExtraFieldAndCommentData) {
  auto write_le16 = [](std::string& s, uint16_t val) {
    s.push_back(static_cast<char>(val & 0xff));
    s.push_back(static_cast<char>((val >> 8) & 0xff));
  };
  auto write_le32 = [](std::string& s, uint32_t val) {
    s.push_back(static_cast<char>(val & 0xff));
    s.push_back(static_cast<char>((val >> 8) & 0xff));
    s.push_back(static_cast<char>((val >> 16) & 0xff));
    s.push_back(static_cast<char>((val >> 24) & 0xff));
  };

  std::string zip;
  std::string file1_name = "[Content_Types].xml";
  std::string file1_data = "<Types></Types>";
  std::string file1_extra = "EX1";
  std::string file1_cmt = "CM1";

  std::string file2_name = "doc.xml";
  std::string file2_data = "<Document/>";
  std::string file2_extra = "EXTRA2";
  std::string file2_cmt = "CMT2";

  // LFH 1
  uint32_t lfh1_offset = zip.size();
  zip.append("PK\x03\x04", 4);
  write_le16(zip, 10);
  write_le16(zip, 0x0008);  // Has data descriptor
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 0);
  write_le16(zip, file1_name.size());
  write_le16(zip, file1_extra.size());
  zip.append(file1_name);
  zip.append(file1_extra);
  zip.append(file1_data);
  // Data descriptor with signature
  zip.append("PK\x07\x08", 4);
  write_le32(zip, 0x12345678);
  write_le32(zip, file1_data.size());
  write_le32(zip, file1_data.size());

  // LFH 2
  uint32_t lfh2_offset = zip.size();
  zip.append("PK\x03\x04", 4);
  write_le16(zip, 10);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0x87654321);
  write_le32(zip, file2_data.size());
  write_le32(zip, file2_data.size());
  write_le16(zip, file2_name.size());
  write_le16(zip, file2_extra.size());
  zip.append(file2_name);
  zip.append(file2_extra);
  zip.append(file2_data);

  // CD Start
  uint32_t cd_offset = zip.size();
  // CD 1
  zip.append("PK\x01\x02", 4);
  write_le16(zip, 20);
  write_le16(zip, 10);
  write_le16(zip, 0x0008);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0x12345678);
  write_le32(zip, file1_data.size());
  write_le32(zip, file1_data.size());
  write_le16(zip, file1_name.size());
  write_le16(zip, file1_extra.size());
  write_le16(zip, file1_cmt.size());
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, lfh1_offset);
  zip.append(file1_name);
  zip.append(file1_extra);
  zip.append(file1_cmt);

  // CD 2
  zip.append("PK\x01\x02", 4);
  write_le16(zip, 20);
  write_le16(zip, 10);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0x87654321);
  write_le32(zip, file2_data.size());
  write_le32(zip, file2_data.size());
  write_le16(zip, file2_name.size());
  write_le16(zip, file2_extra.size());
  write_le16(zip, file2_cmt.size());
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, lfh2_offset);
  zip.append(file2_name);
  zip.append(file2_extra);
  zip.append(file2_cmt);

  uint32_t cd_size = zip.size() - cd_offset;
  // EOCD
  zip.append("PK\x05\x06", 4);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 2);
  write_le16(zip, 2);
  write_le32(zip, cd_size);
  write_le32(zip, cd_offset);
  write_le16(zip, 0);

  riegeli::StringReader source_reader(zip);
  auto source_zip_reader = ZipReader::Create(&source_reader);
  ABSL_ASSERT_OK(source_zip_reader);
  std::vector<ZipReader::FileEntry> file_entries;
  while ((*source_zip_reader)->HasNext()) {
    auto entry = (*source_zip_reader)->Next();
    ABSL_ASSERT_OK(entry);
    file_entries.push_back(*entry);
  }
  ASSERT_EQ(file_entries.size(), 2);

  std::string output_s;
  riegeli::StringWriter<> destination(&output_s);

  auto copy_and_allocate_result = ZipEmbedder().CopyAndAllocate(
      &source_reader, file_entries, /*manifest_store_size=*/100, &destination);
  ABSL_ASSERT_OK(copy_and_allocate_result);
  (void)*copy_and_allocate_result;
  ASSERT_TRUE(destination.Close());

  riegeli::StringReader output_reader(output_s);
  auto out_zip_reader = ZipReader::Create(&output_reader);
  ABSL_ASSERT_OK(out_zip_reader);
  std::vector<ZipReader::FileEntry> out_file_entries;
  while ((*out_zip_reader)->HasNext()) {
    auto entry = (*out_zip_reader)->Next();
    ABSL_ASSERT_OK(entry);
    out_file_entries.push_back(*entry);
  }

  // Expect 3 entries in output: doc.xml, [Content_Types].xml, and manifest
  // store
  EXPECT_EQ(out_file_entries.size(), 3);

  // Check doc.xml retains extra_field_length and file_comment_length
  const ZipReader::FileEntry* doc_entry = nullptr;
  for (const auto& entry : out_file_entries) {
    if (entry.file_name == file2_name) {
      doc_entry = &entry;
    }
  }
  ASSERT_NE(doc_entry, nullptr);
  EXPECT_EQ(doc_entry->extra_field_length, file2_extra.size());
  EXPECT_EQ(doc_entry->file_comment_length, file2_cmt.size());

  // Check extra field data and comment data are present in output string
  EXPECT_THAT(output_s, HasSubstr(file1_extra));
  EXPECT_THAT(output_s, HasSubstr(file1_cmt));
  EXPECT_THAT(output_s, HasSubstr(file2_extra));
  EXPECT_THAT(output_s, HasSubstr(file2_cmt));
}

}  // namespace
}  // namespace credentio
