use "../std/crypto/password"

start:
    let exact_limit: Result[Bytes, Text] = bytes_from_text_bounded("abc", 3)
    assert result_is_ok(exact_limit)
    assert bytes_length(result_unwrap(exact_limit)) == 3
    let over_limit: Result[Bytes, Text] = bytes_from_text_bounded("abc", 2)
    assert not result_is_ok(over_limit)
    let multibyte_over_limit: Result[Bytes, Text] = bytes_from_text_bounded("é", 1)
    assert not result_is_ok(multibyte_over_limit)

    let generated: Result[Text, PasswordHashError] = password_hash_argon2id("correct horse battery staple")
    assert result_is_ok(generated)
    let encoded: Text = result_unwrap(generated)
    assert text_starts_with(encoded, "$argon2id$v=19$m=19456,t=2,p=1$")
    assert not password_hash_needs_rehash(encoded)

    var password_parts: TextList = text_list()
    var password_index: Number = 0
    while password_index < 1025:
        list_push(password_parts, "x")
        set password_index = password_index + 1
    let oversized_password: Text = text_join(password_parts, "")
    let oversized_hash_result: Result[Text, PasswordHashError] = password_hash_argon2id(oversized_password)
    assert not result_is_ok(oversized_hash_result)
    let oversized_verify_result: Result[Boolean, PasswordHashError] = password_verify_argon2id(oversized_password, encoded)
    assert not result_is_ok(oversized_verify_result)

    let another_generated: Result[Text, PasswordHashError] = password_hash_argon2id("correct horse battery staple")
    assert result_is_ok(another_generated)
    assert result_unwrap(another_generated) != encoded

    let correct: Result[Boolean, PasswordHashError] = password_verify_argon2id("correct horse battery staple", encoded)
    assert result_is_ok(correct)
    assert result_unwrap(correct)

    let incorrect: Result[Boolean, PasswordHashError] = password_verify_argon2id("wrong password", encoded)
    assert result_is_ok(incorrect)
    assert not result_unwrap(incorrect)

    assert password_hash_needs_rehash("$argon2id$v=19$m=999999999,t=2,p=1$invalid$invalid")
    let unsupported: Result[Boolean, PasswordHashError] = password_verify_argon2id("password", "$argon2id$v=19$m=999999999,t=2,p=1$invalid$invalid")
    assert not result_is_ok(unsupported)

    let malformed: Result[Boolean, PasswordHashError] = password_verify_argon2id("password", "not-a-password-hash")
    assert not result_is_ok(malformed)
