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

#include <optional>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "formats/gif/constants.h"
#include "formats/gif/test_builder.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/base/types.h"
#include "riegeli/bytes/reader.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

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

class NoSizeStringReader : public riegeli::StringReader<> {
 public:
  using riegeli::StringReader<>::StringReader;
  bool SupportsSize() override { return false; }
};

class SizeNotValuedStringReader : public riegeli::StringReader<> {
 public:
  using riegeli::StringReader<>::StringReader;
  bool SupportsSize() override { return true; }

 protected:
  std::optional<riegeli::Position> SizeImpl() override { return std::nullopt; }
};

absl::StatusOr<GifBlock> GetLastBlock(riegeli::Reader& input) {
  GifBlock last_block;
  if (auto status = IterateOverGifBlocks(input,
                                         [&last_block](const GifBlock& block) {
                                           last_block = block;
                                           return true;
                                         });
      !status.ok()) {
    return status;
  }
  return last_block;
}

TEST(GifReaderTest, ReadsHeader) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 0,
                                       .length = 6,
                                       .type = "GIF89a",
                                   }));
}

TEST(GifReaderTest, FailsOnInvalidHeader) {
  std::string contents = "GIF87a";

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(GifReaderTest, ReadsLogicalDescriptorWithoutColorTable) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 6,
                                       .length = 7,
                                       .type = "LSD",
                                   }));
}

TEST(GifReaderTest, ReadsLogicalDescriptorWithColorTable) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/true);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 6,
                                       .length = 19,
                                       .type = "LSD",
                                   }));
}

TEST(GifReaderTest, ReadsPlainTextExtension) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionPlainText, "ext_info",
                   "plain_text_data");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 28,
                                       .type = "2101",
                                   }));
}

TEST(GifReaderTest, ReadsInvalidExtensionIntroducer) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, 0x0d);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input),
              StatusIs(absl::StatusCode::kUnimplemented,
                       HasSubstr("Extension Type not supported: 0x0d")));
}

TEST(GifReaderTest, ReadsGraphicsControlExtension) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionGraphicsControl,
                   "ext_info", "gce");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 16,
                                       .type = "21F9",
                                   }));
}

TEST(GifReaderTest, ReadsComment) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionComment, "ext_info",
                   "comment");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 20,
                                       .type = "21FE",
                                   }));
}

TEST(GifReaderTest, ReadsTrailer) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifTrailerIntroducer);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 1,
                                       .type = "3B",
                                   }));
}

TEST(GifReaderTest, ReadsTableData) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(0x02, /*type=*/std::nullopt, /*info=*/std::nullopt,
                   "this_is_some_image_data");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 26,
                                       .type = "TBID",
                                   }));
}

TEST(GifReaderTest, ReadsImageDescriptorWithoutColorTable) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddImageDescriptor(/*has_color_table=*/false);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 10,
                                       .type = "2C",
                                   }));
}

TEST(GifReaderTest, ReadsImageDescriptorWithColorTable) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddImageDescriptor(/*has_color_table=*/true);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 22,
                                       .type = "2C",
                                   }));
}

TEST(GifReaderTest, ReadsApplicationExtension) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionApplication,
                   "ext_info", "data");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 17,
                                       .type = "21FF",
                                   }));
}

TEST(GifReaderTest, ReadsC2paExtension) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionApplication,
                   std::string(kGifC2paIdentifier) + "___", "manifest_store");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 13,
                                       .length = 30,
                                       .type = "C2PA",
                                   }));
}

TEST(GifReaderTest, ReadsPastTrailer) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifTrailerIntroducer);
  std::string contents = builder.GetAsset() + "random_data_past_the_trailer";

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(GetLastBlock(input), IsOkAndHolds(GifBlock{
                                       .offset = 14,
                                       .length = 28,
                                       .type = "c2pa.after",
                                   }));
}

TEST(GifReaderTest, FailsWhenSizeNotSupported) {
  std::string contents = "test";
  NoSizeStringReader input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input, [](const GifBlock& block) { return true; }),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("Input does not support size")));
}

TEST(GifReaderTest, FailsWhenSizeHasNoValue) {
  std::string contents = "test";
  SizeNotValuedStringReader input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input, [](const GifBlock& block) { return true; }),
      StatusIs(absl::StatusCode::kInvalidArgument,
               HasSubstr("Input does not support size")));
}

TEST(GifReaderTest, StopsAtHeaderIfProcessorReturnsFalse) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  int call_count = 0;
  EXPECT_THAT(IterateOverGifBlocks(input,
                                   [&](const GifBlock& block) {
                                     call_count++;
                                     return false;
                                   }),
              IsOk());

  EXPECT_EQ(call_count, 1);
}

TEST(GifReaderTest, StopsAtLogicalDescriptorIfProcessorReturnsFalse) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionPlainText, "ext_info",
                   "plain_text_data");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  int call_count = 0;
  EXPECT_THAT(IterateOverGifBlocks(input,
                                   [&](const GifBlock& block) {
                                     call_count++;
                                     if (block.type == "LSD") {
                                       return false;
                                     }
                                     return true;
                                   }),
              IsOk());

  EXPECT_EQ(call_count, 2);
}

TEST(GifReaderTest, StopsInsideLoopIfProcessorReturnsFalse) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionPlainText, "ext_info",
                   "plain_text_data");
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionComment, "ext_info",
                   "comment");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  int call_count = 0;
  EXPECT_THAT(
      IterateOverGifBlocks(input,
                           [&](const GifBlock& block) {
                             call_count++;
                             if (block.type == "2101") {  // PlainText extension
                               return false;
                             }
                             return true;
                           }),
      IsOk());

  EXPECT_EQ(call_count, 3);  // Header, LSD, PlainText
}

TEST(GifReaderTest, FailsWhenReaderFailsDuringLogicalDescriptor) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input,
                           [&](const GifBlock& block) {
                             if (block.type == "GIF89a") {
                               input.Fail(
                                   absl::InternalError("forced read error"));
                             }
                             return true;
                           }),
      StatusIs(absl::StatusCode::kInternal, HasSubstr("forced read error")));
}

TEST(GifReaderTest, FailsWhenSeekFailsAfterLogicalDescriptor) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input,
                           [&](const GifBlock& block) {
                             if (block.type == "LSD") {
                               input.Fail(
                                   absl::InternalError("forced seek error"));
                             }
                             return true;
                           }),
      StatusIs(absl::StatusCode::kInternal, HasSubstr("forced seek error")));
}

TEST(GifReaderTest, FailsWhenSeekFailsInsideLoop) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionPlainText, "ext_info",
                   "plain_text_data");
  std::string contents = builder.GetAsset();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(IterateOverGifBlocks(input,
                                   [&](const GifBlock& block) {
                                     if (block.type == "2101") {
                                       input.Fail(absl::InternalError(
                                           "forced seek error inside loop"));
                                     }
                                     return true;
                                   }),
              StatusIs(absl::StatusCode::kInternal,
                       HasSubstr("forced seek error inside loop")));
}

TEST(GifReaderTest, FailsWhenSeekToEndOfDataFailsOnReadByte) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionPlainText, "ext_info",
                   "plain_text_data");
  std::string contents = builder.GetAsset();
  // Truncate the last byte of the block, which should be the 0x00 termination
  // byte.
  contents.pop_back();

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input, [](const GifBlock& block) { return true; }),
      StatusIs(absl::StatusCode::kDataLoss, HasSubstr("Failed to read byte")));
}

TEST(GifReaderTest, FailsWhenSeekToEndOfDataFailsOnSkip) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionPlainText, "ext_info",
                   "plain_text_data");
  std::string contents = builder.GetAsset();
  // Truncate the contents by 5 bytes (so skip will fail because we claim size
  // is 15 but only 10 left).
  for (int i = 0; i < 5; i++) {
    contents.pop_back();
  }

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input, [](const GifBlock& block) { return true; }),
      StatusIs(absl::StatusCode::kInternal,
               HasSubstr("Failed to seek to offset")));
}

TEST(GifReaderTest, FailsOnHeaderTooShort) {
  std::string contents = "GIF";

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input, [](const GifBlock& block) { return true; }),
      StatusIs(absl::StatusCode::kDataLoss,
               HasSubstr("Failed to read GIF header block")));
}

TEST(GifReaderTest, FailsOnDescriptorTooShort) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  std::string contents = builder.GetAsset() + "123";  // Only 3 bytes for LSD

  riegeli::StringReader<> input(contents);

  EXPECT_THAT(
      IterateOverGifBlocks(input, [](const GifBlock& block) { return true; }),
      StatusIs(absl::StatusCode::kDataLoss,
               HasSubstr("Failed to read descriptor")));
}

}  // namespace
}  // namespace credentio
