using System;
using System.Security.Cryptography;
using System.Text;

namespace MarketData.Security
{
  public class Encryption
  {
    public static string HashPassword(string password)
    {
      using (SHA256 sha256 = SHA256.Create())
      {
        byte[] bytes = Encoding.UTF8.GetBytes(password);
        byte[] hashBytes = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hashBytes);
      }
    }

    public static (string Salt, string Hash) HashPasswordWithSalt(string password)
    {
      using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
      {
        byte[] salt = new byte[16];
        rng.GetBytes(salt);
        using (SHA256 sha256 = SHA256.Create())
        {
          byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
          byte[] saltedPassword = new byte[passwordBytes.Length + salt.Length];
          Buffer.BlockCopy(passwordBytes, 0, saltedPassword, 0, passwordBytes.Length);
          Buffer.BlockCopy(salt, 0, saltedPassword, passwordBytes.Length, salt.Length);
          byte[] hashBytes = sha256.ComputeHash(saltedPassword);
          return (Convert.ToBase64String(salt), Convert.ToBase64String(hashBytes));
        }
      }
    }

    public static bool VerifyPassword(string inputPassword, string storedSalt, string storedHash)
    {
      byte[] salt = Convert.FromBase64String(storedSalt);
      byte[] passwordBytes = Encoding.UTF8.GetBytes(inputPassword);
      byte[] saltedPassword = new byte[passwordBytes.Length + salt.Length];
      Buffer.BlockCopy(passwordBytes, 0, saltedPassword, 0, passwordBytes.Length);
      Buffer.BlockCopy(salt, 0, saltedPassword, passwordBytes.Length, salt.Length);
      using (SHA256 sha256 = SHA256.Create())
      {
        byte[] hashBytes = sha256.ComputeHash(saltedPassword);
        string inputHash = Convert.ToBase64String(hashBytes);
        return inputHash == storedHash;
      }
    }
  }
}
