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

#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 "absl/types/span.h"
#include "formats/png/test_utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

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

absl::StatusOr<std::vector<PngChunk>> GetChunks(riegeli::Reader& reader) {
  std::vector<PngChunk> chunks;
  ABSL_RETURN_IF_ERROR(IterateOverPngChunks(reader, [&](const PngChunk& chunk) {
    chunks.push_back(std::move(chunk));
    return absl::OkStatus();
  }));
  return chunks;
}

absl::StatusOr<std::vector<PngChunk>> GetChunksFromContents(
    absl::string_view contents) {
  riegeli::StringReader reader(contents);
  return GetChunks(reader);
}

using PngReaderTest = testing::Test;

TEST_F(PngReaderTest, NoData) {
  EXPECT_THAT(GetChunksFromContents(""), IsOkAndHolds(IsEmpty()));
}

TEST_F(PngReaderTest, InvalidHeader) {
  std::string content = "abcdefghijklmnopqrstuvwxyz";

  EXPECT_THAT(GetChunksFromContents(content),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("input does not start with PNG marker")));
}

TEST_F(PngReaderTest, ClosedReader) {
  std::string content = "abcdefghijklmnopqrstuvwxyz";

  riegeli::StringReader reader(content);
  EXPECT_TRUE(reader.Close());

  EXPECT_THAT(
      GetChunks(reader),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("PNG reader does not support size, cannot iterate")));
}

TEST_F(PngReaderTest, ChunkExtendsBeyondEndOfFile) {
  auto content_or = CreatePng({{.type = 'IDAT', .payload = "a"}});
  if (!content_or.ok()) {
    FAIL() << "Failed to create PNG: " << content_or.status();
  }
  std::string content = *content_or;
  content[11] = '\xff';  // Marks the IDAT chunk as 255 bytes long.

  EXPECT_THAT(
      GetChunksFromContents(content),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("PNG chunk extends beyond the end of the file")));
}

TEST_F(PngReaderTest, ChunkLengthOverflowPrevention) {
  auto content_or = CreatePng({{.type = 'IDAT', .payload = "a"}});
  ASSERT_TRUE(content_or.ok());
  std::string content = *content_or;
  content[8] = '\xff';
  content[9] = '\xff';
  content[10] = '\xff';
  content[11] = '\xf4';  // data_length = 0xfffffff4 (-12 in 32-bit)

  EXPECT_THAT(
      GetChunksFromContents(content),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("PNG chunk extends beyond the end of the file")));
}

TEST_F(PngReaderTest, InvalidChunkType) {
  auto content_or = CreatePng({{.type = 'C2PA', .payload = "a"}});
  ASSERT_TRUE(content_or.ok());

  EXPECT_THAT(GetChunksFromContents(*content_or),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Invalid PNG chunk type name: C2PA")));
}

}  // namespace
}  // namespace credentio
