defmodule Argon2.Benchmark do
  @moduledoc """
  Benchmarking utilities for Argon2 password hashing.
  """

  def run(rounds \\ 5) do
    configs = [nil, "strong"]
    password = "benchmark_password123"

    IO.puts("Configuration Benchmarks (averaged over #{rounds} runs):\n")

    for config <- configs do
      {hash_times, verify_times} = measure_times(password, config, rounds)
      print_results(config || "owasp", hash_times, verify_times)
    end
  end

  defp measure_times(password, config, rounds) do
    hash_times =
      for _ <- 1..rounds do
        {time, hash} = :timer.tc(fn -> Argon2.hash_password(password, config) end)
        {verify_time, _} = :timer.tc(fn -> Argon2.verify_password(password, hash) end)
        # Convert to milliseconds
        {time / 1000, verify_time / 1000}
      end

    {hash_avg, verify_avg} =
      Enum.reduce(hash_times, {0, 0}, fn {h, v}, {ha, va} ->
        {ha + h / rounds, va + v / rounds}
      end)

    {hash_avg, verify_avg}
  end

  defp print_results(config, hash_avg, verify_avg) do
    memory =
      case config do
        "owasp" -> 19
        "strong" -> 65
      end

    IO.puts("""
    #{String.upcase(config)}:
      Hash time: #{round(hash_avg)}ms
      Verify time: #{round(verify_avg)}ms
      Memory: #{memory}MB
    """)
  end
end