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

#include <memory>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/status_matchers.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
#include "crypto/algorithms.h"
#include "crypto/default/hasher.h"
#include "crypto/hash.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "riegeli/bytes/string_reader.h"

namespace credentio {
namespace {

using ::absl_testing::IsOk;
using ::absl_testing::StatusIs;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Return;

std::string Sha256Digest(absl::string_view data) {
  absl::StatusOr<std::unique_ptr<Hasher>> hasher = CreateHasher("sha256");
  if (!hasher.ok()) return "";
  (*hasher)->Update(data);
  return (*hasher)->Digest();
}

TEST(InputHasherTest, CreateWithValidAlgString) {
  EXPECT_THAT(InputHasher::Create("sha256"), IsOk());
  EXPECT_THAT(InputHasher::Create("sha384"), IsOk());
  EXPECT_THAT(InputHasher::Create("sha512"), IsOk());
}

TEST(InputHasherTest, CreateWithInvalidAlgString) {
  EXPECT_THAT(InputHasher::Create("invalid"),
              StatusIs(absl::StatusCode::kInvalidArgument));
}

TEST(InputHasherTest, CreateWithValidAlgEnum) {
  EXPECT_THAT(InputHasher::Create(HashAlgorithm::kSha256), IsOk());
  EXPECT_THAT(InputHasher::Create(HashAlgorithm::kSha384), IsOk());
  EXPECT_THAT(InputHasher::Create(HashAlgorithm::kSha512), IsOk());
}

class MockHasher : public Hasher {
 public:
  MOCK_METHOD(void, Update, (absl::string_view data), (override));
  MOCK_METHOD(std::string, Digest, (), (override));
};

TEST(InputHasherTest, CreateWithCustomHasher) {
  auto mock_hasher = std::make_unique<MockHasher>();
  EXPECT_CALL(*mock_hasher, Update("test"));
  EXPECT_CALL(*mock_hasher, Digest()).WillOnce(Return("mock_digest"));

  auto input_hasher = InputHasher::Create(std::move(mock_hasher));
  ASSERT_THAT(input_hasher, IsOk());
  (*input_hasher)->Update("test");
  EXPECT_THAT((*input_hasher)->Digest(), Eq("mock_digest"));
}

TEST(InputHasherTest, UpdateStringView) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  (*hasher)->Update("hello");
  (*hasher)->Update(" ");
  (*hasher)->Update("world");

  EXPECT_THAT(absl::BytesToHexString((*hasher)->Digest()),
              Eq(absl::BytesToHexString(Sha256Digest("hello world"))));
}

TEST(InputHasherTest, UpdateRiegeliEmpty) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  std::string data = "";
  riegeli::StringReader reader(data);
  EXPECT_THAT((*hasher)->Update(reader, 0, 0), IsOk());

  EXPECT_THAT(absl::BytesToHexString((*hasher)->Digest()),
              Eq(absl::BytesToHexString(Sha256Digest(data))));
}

TEST(InputHasherTest, UpdateRiegeliSmall) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  std::string data = "small data";
  riegeli::StringReader reader(data);
  EXPECT_THAT((*hasher)->Update(reader, 0, data.length()), IsOk());

  EXPECT_THAT(absl::BytesToHexString((*hasher)->Digest()),
              Eq(absl::BytesToHexString(Sha256Digest(data))));
}

TEST(InputHasherTest, UpdateRiegeliLarge) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  std::string data(20000, 'a');  // Larger than default chunk size
  riegeli::StringReader reader(data);
  EXPECT_THAT((*hasher)->Update(reader, 0, data.length()), IsOk());

  EXPECT_THAT(absl::BytesToHexString((*hasher)->Digest()),
              Eq(absl::BytesToHexString(Sha256Digest(data))));
}

TEST(InputHasherTest, UpdateRiegeliWithOffset) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  std::string data = "prefix_and_data";
  riegeli::StringReader reader(data);
  EXPECT_THAT((*hasher)->Update(reader, 7, 3), IsOk());  // "and"

  EXPECT_THAT(absl::BytesToHexString((*hasher)->Digest()),
              Eq(absl::BytesToHexString(Sha256Digest("and"))));
}

TEST(InputHasherTest, UpdateRiegeliMultiple) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  std::string data1 = "first part";
  std::string data2 = " second part";

  riegeli::StringReader reader1(data1);
  riegeli::StringReader reader2(data2);

  EXPECT_THAT((*hasher)->Update(reader1, 0, data1.length()), IsOk());
  (*hasher)->Update(" middle ");
  EXPECT_THAT((*hasher)->Update(reader2, 0, data2.length()), IsOk());

  EXPECT_THAT(absl::BytesToHexString((*hasher)->Digest()),
              Eq(absl::BytesToHexString(
                  Sha256Digest("first part middle  second part"))));
}

TEST(InputHasherTest, UpdateRiegeliClosedReaderFails) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  riegeli::StringReader reader("test");
  reader.Close();

  EXPECT_THAT((*hasher)->Update(reader, 0, 4),
              StatusIs(absl::StatusCode::kFailedPrecondition,
                       HasSubstr("Object closed")));
}

TEST(InputHasherTest, UpdateRiegeliOffsetOutOfRange) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  riegeli::StringReader reader("test");

  EXPECT_THAT(
      (*hasher)->Update(reader, 10, 4),
      StatusIs(absl::StatusCode::kInternal, HasSubstr("Failed to seek to 10")));
}

TEST(InputHasherTest, UpdateRiegeliLengthExceedsSourceFails) {
  auto hasher = InputHasher::Create("sha256");
  ASSERT_THAT(hasher, IsOk());
  riegeli::StringReader reader("test");

  EXPECT_THAT((*hasher)->Update(reader, 0, 100),
              StatusIs(absl::StatusCode::kDataLoss,
                       HasSubstr("Failed to read from source")));
}

}  // namespace
}  // namespace credentio
