using System.Text;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;

namespace HashService {

  public interface IHashService {
    (string, string) CreateSaltedHash(string value);
    bool ValidateHash(string value, string salt, string hash);
  }
  public class HashService : IHashService {
    private string CreateSalt() {
      byte[] randomBytes = new byte[128 / 8];
      using (var generator = RandomNumberGenerator.Create()) {
        generator.GetBytes(randomBytes);
        return Convert.ToBase64String(randomBytes);
      }
    }

    private string CreateHash(string value, string salt) {
      var valueBytes = KeyDerivation.Pbkdf2(
        password: value,
        salt: Encoding.UTF8.GetBytes(salt),
        prf: KeyDerivationPrf.HMACSHA512,
        iterationCount: 10000,
        numBytesRequested: 256 / 8);

      return Convert.ToBase64String(valueBytes);
    }

    public (string, string) CreateSaltedHash(string value) {
      var salt = CreateSalt();
      var hash = CreateHash(value, salt);

      return (salt, hash);
    }

    public bool ValidateHash(string value, string salt, string hash) =>
      CreateHash(value, salt) == hash;
  }
}
