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

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

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "bindings/input_hasher.h"
#include "crypto/default/hasher.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::IsOk;
using ::absl_testing::StatusIs;
using ::credentio::BindingHasher::Chunk::Op::kExclusion;
using ::credentio::BindingHasher::Chunk::Op::kInclusion;
using ::credentio::BindingHasher::Chunk::Op::kInsertion;
using ::testing::HasSubstr;
using ::testing::IsNull;
using ::testing::NotNull;
using ::testing::Optional;

class ErrorHasher : public InputHasher {
 public:
  absl::Status Update(riegeli::Reader& input, uint64_t offset,
                      uint64_t length) override {
    return absl::InvalidArgumentError("error");
  }
  void Update(absl::string_view data) override {}
  std::string Digest() override { return ""; }
};

std::string Sha256Digest(absl::string_view contents) {
  auto hasher = CreateHasher("sha256");
  if (!hasher.ok()) return "";
  (*hasher)->Update(contents);
  return (*hasher)->Digest();
}

TEST(BmffHasher, OkayEntireContent) {
  StatusBindingHasherTracker tracker;
  auto input = "0123456789";
  auto hasher = BindingHasher::Create("sha256", /*chunks=*/{}, tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("0123456789")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayLargeContent) {
  StatusBindingHasherTracker tracker;
  std::string input;
  for (int i = 0; i < 2000; ++i) {
    absl::StrAppend(&input, "abcdefg");
  }

  auto hasher = BindingHasher::Create("sha256", /*chunks=*/{}, tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest(input)));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayExclusions) {
  StatusBindingHasherTracker tracker;
  auto input = "0123456789";

  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kExclusion, .offset = 1, .length = 1},
                             {.op = kExclusion, .offset = 3, .length = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("0256789")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayExcludingTheRestOfFile) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kExclusion, .offset = 1, .length = 1},
                             {.op = kExclusion, .offset = 3, .length = 0}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("02")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayInsertions) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256",
      {{.op = kInsertion, .offset = 1, .additional_data = "AAA"},
       {.op = kInsertion, .offset = 7, .additional_data = "BBB"}},
      tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("0AAA123456BBB789")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayInsertionsAndIgnoreChunkSize) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256",
      {{.op = kInsertion, .offset = 1, .length = 100, .additional_data = "AAA"},
       {.op = kInsertion, .offset = 7, .additional_data = "BBB"}},
      tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("0AAA123456BBB789")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayMixingExclusionsAndInsertions) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256",
      {{.op = kExclusion, .offset = 1, .length = 1},
       {.op = kInsertion, .offset = 2, .additional_data = "AAA"},
       {.op = kExclusion, .offset = 3, .length = 2},
       {.op = kInsertion, .offset = 7, .additional_data = "BBB"}},
      tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("0AAA256BBB789")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, OkayInclusions) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kInclusion, .offset = 1, .length = 1},
                             {.op = kInclusion, .offset = 3, .length = 2},
                             {.op = kInclusion,
                              .offset = 6,
                              /* .length = 0 */}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  EXPECT_THAT(result, Optional(Sha256Digest("1346789")));
  EXPECT_THAT(tracker.status(), IsOk());
}

TEST(BmffHasher, ErrorMixedInclusionsAndExclusions) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kExclusion, .offset = 1, .length = 1},
                             {.op = kInclusion, .offset = 3, .length = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorInsertingOutOfInput) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256", {{.op = kInsertion, .offset = 10}}, tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorExclusionOverlapping) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kExclusion,
                              .offset = 1,
                              .length = 0},  // exclude the rest of file.
                             {.op = kExclusion, .offset = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorExclusionOverlappingNonEnd) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kExclusion, .offset = 1, .length = 3},
                             {.op = kExclusion, .offset = 2, .length = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorExclusionOutOfOrder) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kExclusion, .offset = 5, .length = 2},
                             {.op = kExclusion, .offset = 2, .length = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorInclusionOverlapping) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kInclusion, .offset = 1, .length = 3},
                             {.op = kInclusion, .offset = 2, .length = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorInclusionOutOfOrder) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher =
      BindingHasher::Create("sha256",
                            {{.op = kInclusion, .offset = 5, .length = 2},
                             {.op = kInclusion, .offset = 2, .length = 2}},
                            tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, DigestUnorderedExclusionsCPUExhaustionLoop) {
  std::string input(1000, 'a');
  std::vector<BindingHasher::Chunk> chunks;
  for (int i = 0; i < 1000; ++i) {
    chunks.push_back(
        {.op = kExclusion, .offset = (i % 2 == 0) ? 500u : 10u, .length = 5});
  }

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create("sha256", chunks, tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorChunkMalformed) {
  auto input = "0123456789";
  riegeli::StringReader<> reader(input);

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256", {{.op = kExclusion, .offset = 3, .length = -1}}, tracker);
  ASSERT_THAT(hasher, NotNull());
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("malformed")));
}

TEST(BmffHasher, ErrorExclusionMismatch) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256", {{.op = kExclusion, .offset = 3, .length = 10}}, tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("mismatch")));
}

TEST(BmffHasher, ErrorInclusionMismatch) {
  auto input = "0123456789";

  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create(
      "sha256", {{.op = kInclusion, .offset = 3, .length = 10}}, tracker);
  ASSERT_THAT(hasher, NotNull());
  riegeli::StringReader<> reader(input);
  auto result = hasher->Digest(reader, tracker);
  ASSERT_FALSE(result.has_value());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("mismatch")));
}

TEST(BmffHasher, ErrorAlgorithmUnsupported) {
  StatusBindingHasherTracker tracker;
  auto hasher = BindingHasher::Create("abcd", {}, tracker);
  EXPECT_THAT(hasher, IsNull());
  EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument,
                                         HasSubstr("unsupported")));
}

TEST(BmffHasher, ErrorHasherFailed) {
  {
    auto input = "0123456789";

    StatusBindingHasherTracker tracker;
    BindingHasher hasher(std::make_unique<ErrorHasher>(), /*chunks=*/{});
    riegeli::StringReader<> reader(input);
    auto result = hasher.Digest(reader, tracker);
    ASSERT_FALSE(result.has_value());
    EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument));
  }
  {
    auto input = "0123456789";

    StatusBindingHasherTracker tracker;
    BindingHasher hasher(std::make_unique<ErrorHasher>(),
                         {{.op = kExclusion, .offset = 1, .length = 1}});
    riegeli::StringReader<> reader(input);
    auto result = hasher.Digest(reader, tracker);
    ASSERT_FALSE(result.has_value());
    EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument));
  }
  {
    auto input = "0123456789";

    StatusBindingHasherTracker tracker;
    BindingHasher hasher(
        std::make_unique<ErrorHasher>(),
        {{.op = kInsertion, .offset = 0, .additional_data = "AAA"}});
    riegeli::StringReader<> reader(input);
    auto result = hasher.Digest(reader, tracker);
    ASSERT_FALSE(result.has_value());
    EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument));
  }
  {
    auto input = "0123456789";

    StatusBindingHasherTracker tracker;
    BindingHasher hasher(std::make_unique<ErrorHasher>(),
                         {{.op = kInclusion, .offset = 0}});
    riegeli::StringReader<> reader(input);
    auto result = hasher.Digest(reader, tracker);
    ASSERT_FALSE(result.has_value());
    EXPECT_THAT(tracker.status(), StatusIs(absl::StatusCode::kInvalidArgument));
  }
}

}  // namespace
}  // namespace credentio
