// 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.
//

#ifndef THIRD_PARTY_CREDENTIO_CRYPTO_HASH_H_
#define THIRD_PARTY_CREDENTIO_CRYPTO_HASH_H_

#include <memory>
#include <string>

#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "crypto/algorithms.h"

namespace credentio {

// A single-use object for computing a hash of some content.
// For hash checking, use `HashChecker` instead.
class Hasher {
 public:
  virtual ~Hasher() = default;

  // Adds `content` to the data to be hashed. Can be called repeatedly.
  virtual void Update(absl::string_view content) = 0;

  // Returns digest of the previously provided content.
  virtual std::string Digest() = 0;
};

// A hasher for size estimation. Returns all-zero hashes.
class TemplatedHasher : public Hasher {
 public:
  explicit TemplatedHasher(HashAlgorithm algorithm) : algorithm_(algorithm) {}
  void Update(absl::string_view content) override {}
  std::string Digest() override {
    return std::string(HashSizeBytes(algorithm_), '\0');
  }

 private:
  HashAlgorithm algorithm_;
};

// A factory for creating Hashers.
class HasherFactory {
 public:
  virtual ~HasherFactory() = default;
  virtual absl::StatusOr<std::unique_ptr<Hasher>> Create() const = 0;
  virtual HashAlgorithm algorithm() const = 0;
};

// A factory for creating Hashers for size estimation, which return all-zero
// hashes.
class TemplatedHasherFactory : public HasherFactory {
 public:
  explicit TemplatedHasherFactory(HashAlgorithm algorithm)
      : algorithm_(algorithm) {}
  absl::StatusOr<std::unique_ptr<Hasher>> Create() const override {
    return std::make_unique<TemplatedHasher>(algorithm_);
  }
  HashAlgorithm algorithm() const override { return algorithm_; }

 private:
  HashAlgorithm algorithm_;
};

// A single-use checker for checking content against an expected hash.
class HashChecker {
 public:
  virtual ~HashChecker() = default;

  // Adds `content` to the data to be hashed. Can be called repeatedly.
  virtual void Update(absl::string_view content) = 0;

  // Returns true if the hash of the previously provided content matches
  // `expected_hash`.
  virtual bool Check(absl::string_view expected_hash) = 0;
};

// A factory for creating `HashChecker`s.
class HashCheckerFactory {
 public:
  virtual ~HashCheckerFactory() = default;

  // Returns a `HashChecker` for `algorithm` or an error if the algorithm is not
  // supported.
  virtual absl::StatusOr<std::unique_ptr<HashChecker>> Create(
      HashAlgorithm algorithm) const = 0;
};

}  // namespace credentio

#endif  // THIRD_PARTY_CREDENTIO_CRYPTO_HASH_H_
