defmodule Argon2Test do
  use ExUnit.Case
  doctest Argon2

  describe "hash_password/1" do
    test "hashes a password with default OWASP config" do
      hash = Argon2.hash_password("password123")
      assert is_binary(hash)
      assert String.starts_with?(hash, "$argon2i$v=19$m=19456,t=2,p=1$")
    end

    test "hashes a password with strong config" do
      config = "strong"
      hash = Argon2.hash_password("password123", config)
      assert is_binary(hash)
      assert String.starts_with?(hash, "$argon2i$v=19$m=65540,t=3,p=4$")
    end

    test "generates different hashes for the same password" do
      hash1 = Argon2.hash_password("same_password123")
      hash2 = Argon2.hash_password("same_password123")
      refute hash1 == hash2
    end

    test "rejects passwords shorter than 8 characters" do
      assert_raise ArgumentError, "Password must be at least 8 characters long", fn ->
        Argon2.hash_password("short")
      end
    end

    test "accepts passwords exactly 8 characters" do
      hash = Argon2.hash_password("abcdefgh")
      assert is_binary(hash)
    end
  end

  describe "verify_password/2" do
    test "verifies a correct password" do
      password = "correct_password123"
      hash = Argon2.hash_password(password)
      assert Argon2.verify_password(password, hash)
    end

    test "rejects an incorrect password" do
      password = "correct_password123"
      wrong_password = "wrong_password123"
      hash = Argon2.hash_password(password)
      refute Argon2.verify_password(wrong_password, hash)
    end

    test "handles invalid hash format" do
      assert_raise ArgumentError, fn ->
        Argon2.verify_password("password123", "invalid_hash_format")
      end
    end

    test "rejects verification of short passwords" do
      assert_raise ArgumentError, "Password must be at least 8 characters long", fn ->
        Argon2.verify_password("short", "$argon2i$v=19$m=65536,t=2,p=4$c29tZXNhbHQ$hash")
      end
    end
  end

  describe "edge cases" do
    test "handles unicode passwords of sufficient length" do
      password = "パスワード123456"
      hash = Argon2.hash_password(password)
      assert Argon2.verify_password(password, hash)
    end

    test "handles emoji passwords" do
      password = "🏳️‍⚧️🏳️‍⚧️🏳️‍⚧️🏳️‍⚧️🏳️‍⚧️🏳️‍⚧️"
      hash = Argon2.hash_password(password)
      assert Argon2.verify_password(password, hash)
    end

    test "handles very long passwords" do
      long_password = String.duplicate("a", 1000)
      hash = Argon2.hash_password(long_password)
      assert Argon2.verify_password(long_password, hash)
    end
  end
end