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

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

#include "absl/log/check.h"
#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "formats/byte_range.h"
#include "formats/zip/constants.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 "riegeli/endian/endian_writing.h"
#include "testing/jumbf_utils.h"
#include "testing/test_file_utils.h"

namespace credentio {
namespace {

using ::absl_testing::IsOkAndHolds;
using ::absl_testing::StatusIs;
using ::testing::AllOf;
using ::testing::Eq;
using ::testing::Field;
using ::testing::HasSubstr;
using ::testing::Optional;

// A Zip file entry.
struct ZipEntry {
  std::string name;
  std::string content;
};

// Creates a minimal Zip file in memory.
// This is not a full-fledged Zip creator, but enough to satisfy ZipReader.
absl::StatusOr<std::string> CreateFakeZip(absl::Span<const ZipEntry> entries) {
  std::string buffer;
  riegeli::StringWriter writer(&buffer);

  // Write local file headers and data.
  std::vector<uint32_t> offsets;
  for (const auto& entry : entries) {
    offsets.push_back(writer.pos());

    writer.Write(kZipLocalFileHeaderSignature);
    // Version needed to extract (2.0)
    riegeli::WriteLittleEndian<uint16_t>(20, writer);
    // General purpose bit flag
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Compression method (stored)
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Last mod file time
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Last mod file date
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // CRC-32 (0 for now, we don't check it)
    riegeli::WriteLittleEndian<uint32_t>(0, writer);
    // Compressed size
    riegeli::WriteLittleEndian<uint32_t>(entry.content.size(), writer);
    // Uncompressed size
    riegeli::WriteLittleEndian<uint32_t>(entry.content.size(), writer);
    // File name length
    riegeli::WriteLittleEndian<uint16_t>(entry.name.size(), writer);
    // Extra field length
    riegeli::WriteLittleEndian<uint16_t>(0, writer);

    // File name
    writer.Write(entry.name);
    // File data
    writer.Write(entry.content);
  }

  uint32_t central_directory_start_offset = writer.pos();

  // Write central directory.
  for (size_t i = 0; i < entries.size(); ++i) {
    const auto& entry = entries[i];
    writer.Write(kZipCentralDirectorySignature);
    // Version made by
    riegeli::WriteLittleEndian<uint16_t>(20, writer);
    // Version needed to extract
    riegeli::WriteLittleEndian<uint16_t>(20, writer);
    // General purpose bit flag
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Compression method
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Last mod file time
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Last mod file date
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // CRC-32
    riegeli::WriteLittleEndian<uint32_t>(0, writer);
    // Compressed size
    riegeli::WriteLittleEndian<uint32_t>(entry.content.size(), writer);
    // Uncompressed size
    riegeli::WriteLittleEndian<uint32_t>(entry.content.size(), writer);
    // File name length
    riegeli::WriteLittleEndian<uint16_t>(entry.name.size(), writer);
    // Extra field length
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // File comment length
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Disk number start
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // Internal file attributes
    riegeli::WriteLittleEndian<uint16_t>(0, writer);
    // External file attributes
    riegeli::WriteLittleEndian<uint32_t>(0, writer);
    // Relative offset of local header
    riegeli::WriteLittleEndian<uint32_t>(offsets[i], writer);

    // File name
    writer.Write(entry.name);
  }

  uint32_t central_directory_size =
      writer.pos() - central_directory_start_offset;

  // Write End of Central Directory (EOCD) record.
  writer.Write(kZipEndOfCentralDirectorySignature);
  // Number of this disk
  riegeli::WriteLittleEndian<uint16_t>(0, writer);
  // Number of the disk with the start of the central directory
  riegeli::WriteLittleEndian<uint16_t>(0, writer);
  // Total number of entries in the central directory on this disk
  riegeli::WriteLittleEndian<uint16_t>(entries.size(), writer);
  // Total number of entries in the central directory
  riegeli::WriteLittleEndian<uint16_t>(entries.size(), writer);
  // Size of the central directory
  riegeli::WriteLittleEndian<uint32_t>(central_directory_size, writer);
  // Offset of start of central directory with respect to the starting disk
  // number
  riegeli::WriteLittleEndian<uint32_t>(central_directory_start_offset, writer);
  // .ZIP file comment length
  riegeli::WriteLittleEndian<uint16_t>(0, writer);

  if (!writer.Close()) {
    return writer.status();
  }
  return buffer;
}

TEST(ZipExtractorTest, ExtractManifestStore) {
  absl::StatusOr<std::unique_ptr<riegeli::Reader>> input =
      credentio_testing::GetFileReader(
          "credentio/formats/zip/testing/asset_fake_c2pa.zip");
  ABSL_ASSERT_OK(input);

  EXPECT_THAT(ZipExtractor().ExtractManifestStore(**input),
              IsOkAndHolds(HasSubstr("c2pa manifest")));
}

TEST(ZipExtractorTest,
     ExtractManifestStoreThrowsErrorIfMultipleC2paManifestStoresFound) {
  // Create a fake Zip file with duplicate manifest stores.
  absl::StatusOr<std::string> zip_file_contents = CreateFakeZip({
      {.name = "META-INF/content_credential.c2pa",
       .content = "c2pa manifest 1"},
      {.name = "META-INF/content_credential.c2pa",
       .content = "c2pa manifest 2"},
  });
  ABSL_ASSERT_OK(zip_file_contents);
  riegeli::StringReader<> input(*zip_file_contents);

  EXPECT_THAT(ZipExtractor().ExtractManifestStore(input),
              StatusIs(absl::StatusCode::kNotFound,
                       HasSubstr("Multiple manifest stores found")));
}

TEST(ZipExtractorTest, ExtractManifestStoreThrowsNotFoundErrorIfNoC2pa) {
  absl::StatusOr<std::unique_ptr<riegeli::Reader>> input =
      credentio_testing::GetFileReader(
          "credentio/formats/zip/testing/asset_no_c2pa.zip");
  ABSL_ASSERT_OK(input);

  EXPECT_THAT(ZipExtractor().ExtractManifestStore(**input),
              StatusIs(absl::StatusCode::kNotFound,
                       HasSubstr("No manifest store found")));
}

TEST(ZipExtractorTest, ExtractManifestStoreLocation) {
  absl::StatusOr<std::unique_ptr<riegeli::Reader>> input =
      credentio_testing::GetFileReader(
          "credentio/formats/zip/testing/asset_fake_c2pa.zip");
  ABSL_ASSERT_OK(input);

  EXPECT_THAT(ZipExtractor().ExtractManifestStoreLocation(
                  **input, {.requires_c2pa = true}),
              IsOkAndHolds(Optional(AllOf(Field(&ByteRange::offset, Eq(201)),
                                          Field(&ByteRange::length, Eq(14))))));
}

TEST(ZipExtractorTest,
     ExtractManifestStoreLocationReturnsNulloptIfNoC2paAndNotRequired) {
  absl::StatusOr<std::unique_ptr<riegeli::Reader>> input =
      credentio_testing::GetFileReader(
          "credentio/formats/zip/testing/asset_no_c2pa.zip");
  ABSL_ASSERT_OK(input);

  EXPECT_THAT(ZipExtractor().ExtractManifestStoreLocation(
                  **input, {.requires_c2pa = false}),
              IsOkAndHolds(Eq(std::nullopt)));
}

TEST(ZipExtractorTest,
     ExtractManifestStoreLocationReturnsErrorIfNoC2paButRequired) {
  absl::StatusOr<std::unique_ptr<riegeli::Reader>> input =
      credentio_testing::GetFileReader(
          "credentio/formats/zip/testing/asset_no_c2pa.zip");
  ABSL_ASSERT_OK(input);
  EXPECT_THAT(ZipExtractor().ExtractManifestStoreLocation(
                  **input, {.requires_c2pa = true}),
              StatusIs(absl::StatusCode::kNotFound,
                       HasSubstr("No manifest store found")));
}

TEST(ZipExtractorTest, ExtractBoxesReturnsUnimplemented) {
  absl::StatusOr<std::string> zip = CreateFakeZip({});
  ABSL_ASSERT_OK(zip);
  riegeli::StringReader<> input(*zip);

  EXPECT_THAT(ZipExtractor().ExtractBoxes(input, {}),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("ZIP does not have a concept of boxes")));
}

TEST(ZipExtractorTest, IsManifestStore) {
  EXPECT_TRUE(ZipExtractor().MightBeC2paManifestStore(
      CreateStartOfManifestStorePayload()));
  EXPECT_FALSE(ZipExtractor().MightBeC2paManifestStore("not a manifest store"));
}

TEST(ZipExtractorTest,
     ExtractManifestStoreThrowsErrorIfManifestStoreExceedsLimit) {
  std::string large_content(17 * 1024 * 1024, 'a');
  absl::StatusOr<std::string> zip = CreateFakeZip({
      {.name = "META-INF/content_credential.c2pa",
       .content = std::move(large_content)},
  });
  ABSL_ASSERT_OK(zip);
  riegeli::StringReader<> input(*zip);

  EXPECT_THAT(ZipExtractor().ExtractManifestStore(input),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Manifest store size exceeds maximum limit")));
}

TEST(ZipExtractorTest, ExtractManifestStoreThrowsErrorIfCompressed) {
  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;
  zip.append("PK\x03\x04", 4);
  write_le16(zip, 20);
  write_le16(zip, 0);
  write_le16(zip, 8);  // LFH compression method = 8 (deflated)
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 10);
  write_le32(zip, 20);
  std::string filename = "META-INF/content_credential.c2pa";
  write_le16(zip, filename.size());
  write_le16(zip, 0);
  zip.append(filename);
  zip.append("abcdefghij");

  uint32_t cd_offset = zip.size();
  zip.append("PK\x01\x02", 4);
  write_le16(zip, 20);
  write_le16(zip, 20);
  write_le16(zip, 0);
  write_le16(zip, 8);  // CD compression method = 8 (deflated)
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 10);
  write_le32(zip, 20);
  write_le16(zip, filename.size());
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 0);
  zip.append(filename);

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

  riegeli::StringReader<> input(zip);
  EXPECT_THAT(ZipExtractor().ExtractManifestStore(input),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Manifest store must not be compressed")));
}

TEST(ZipExtractorTest,
     ExtractManifestStoreThrowsErrorIfUncompressedSizeExceedsLimit) {
  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;
  zip.append("PK\x03\x04", 4);
  write_le16(zip, 20);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 10);
  write_le32(zip, 17 * 1024 * 1024);  // Uncompressed size = 17MB
  std::string filename = "META-INF/content_credential.c2pa";
  write_le16(zip, filename.size());
  write_le16(zip, 0);
  zip.append(filename);
  zip.append("abcdefghij");

  uint32_t cd_offset = zip.size();
  zip.append("PK\x01\x02", 4);
  write_le16(zip, 20);
  write_le16(zip, 20);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 10);
  write_le32(zip, 17 * 1024 * 1024);
  write_le16(zip, filename.size());
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le16(zip, 0);
  write_le32(zip, 0);
  write_le32(zip, 0);
  zip.append(filename);

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

  riegeli::StringReader<> input(zip);
  EXPECT_THAT(ZipExtractor().ExtractManifestStore(input),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Manifest store size exceeds maximum limit")));
}

}  // namespace
}  // namespace credentio
