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

#include <optional>
#include <string>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "crypto/algorithms.h"
#include "formats/gif/constants.h"
#include "formats/gif/test_builder.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/string_reader.h"
#include "testing/proto_test_utils.h"

namespace credentio {
namespace {

using ::absl_testing::StatusIs;
using ::credentio_testing::EqualsProto;
using ::credentio_testing::ParseTextProtoOrDie;
using ::testing::HasSubstr;

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

  riegeli::StringReader<> input(asset);

  auto result_or = DigestGif(input, HashAlgorithm::kSha256);
  ABSL_ASSERT_OK(result_or);
  EXPECT_TRUE(result_or->existing_c2pa_length.has_value());
  EXPECT_GT(*result_or->existing_c2pa_length, 0);
}

TEST(HasherTest, FailsWhenMultipleC2paBlocksExist) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionApplication,
                   std::string(kGifC2paIdentifier) + "___", "manifest_store_1");
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionApplication,
                   std::string(kGifC2paIdentifier) + "___", "manifest_store_2");
  builder.AddBlock(kGifTrailerIntroducer);
  std::string asset = builder.GetAsset();

  riegeli::StringReader<> input(asset);

  EXPECT_THAT(DigestGif(input, HashAlgorithm::kSha256),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("Unexpected additional C2PA block found")));
}

TEST(HasherTest, FailsWhenC2paBlockAfterImageDescriptor) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddImageDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionApplication,
                   std::string(kGifC2paIdentifier) + "___", "manifest_store");
  builder.AddBlock(kGifTrailerIntroducer);
  std::string asset = builder.GetAsset();

  riegeli::StringReader<> input(asset);

  EXPECT_THAT(
      DigestGif(input, HashAlgorithm::kSha256),
      StatusIs(
          absl::StatusCode::kInvalidArgument,
          HasSubstr("Unexpected C2PA block found after Image Descriptor")));
}

TEST(HasherTest, FailsWhenNoLogicalDescriptor) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  std::string asset = builder.GetAsset();

  riegeli::StringReader<> input(asset);

  EXPECT_THAT(DigestGif(input, HashAlgorithm::kSha256),
              StatusIs(absl::StatusCode::kInvalidArgument,
                       HasSubstr("No Logical Screen Descriptor found in GIF")));
}

TEST(HasherTest, SuccessfullyHashesGif) {
  TestGifBuilder builder;
  builder.AddGifHeader();
  builder.AddLogicalDescriptor(/*has_color_table=*/false);
  builder.AddBlock(kGifExtensionIntroducer, kGifExtensionApplication,
                   "other_app_info", "misc_data");
  builder.AddBlock(kGifTrailerIntroducer);
  std::string asset = builder.GetAsset();

  riegeli::StringReader<> input(asset);

  auto result_or = DigestGif(input, HashAlgorithm::kSha256);
  ABSL_ASSERT_OK(result_or);
  EXPECT_EQ(result_or->insertion_point, GifInsertionPoint{.offset = 13});
  EXPECT_THAT(
      result_or->data_hash,
      EqualsProto(ParseTextProtoOrDie<DataHashAssertion>(R"pb(
        alg: "sha256"
        hash: "\334(\"\336\341 WHK\0219$\202p-\246\373\246t;\310Zd5x\345R\341a_\354s"
        exclusions { start: 13 length: 0 }
      )pb")));
}

}  // namespace
}  // namespace credentio
