"""
Unit tests for Slack OAuth state generation and verification.

Tests:
  - generate_oauth_state produces a base64-encoded string containing tenant_id
  - verify_oauth_state returns the correct tenant_id for a valid state
  - verify_oauth_state raises ValueError for a tampered state
  - verify_oauth_state raises ValueError for a state signed with wrong secret
"""

from __future__ import annotations

import pytest

from shared.api.channels import generate_oauth_state, verify_oauth_state

_SECRET = "test-hmac-secret-do-not-use-in-production"
_TENANT_ID = "550e8400-e29b-41d4-a716-446655440000"


def test_generate_oauth_state_is_string() -> None:
    """generate_oauth_state returns a non-empty string."""
    state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)
    assert isinstance(state, str)
    assert len(state) > 0


def test_generate_oauth_state_contains_tenant_id() -> None:
    """
    generate_oauth_state embeds the tenant_id in the state payload.
    Verifying the state should return the original tenant_id.
    """
    state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)
    recovered = verify_oauth_state(state=state, secret=_SECRET)
    assert recovered == _TENANT_ID


def test_verify_oauth_state_valid() -> None:
    """verify_oauth_state returns correct tenant_id for a freshly generated state."""
    state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)
    result = verify_oauth_state(state=state, secret=_SECRET)
    assert result == _TENANT_ID


def test_verify_oauth_state_tampered() -> None:
    """verify_oauth_state raises ValueError if the state payload is tampered."""
    state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)

    # Tamper: append garbage to the state string
    tampered = state + "TAMPERED"

    with pytest.raises(ValueError):
        verify_oauth_state(state=tampered, secret=_SECRET)


def test_verify_oauth_state_wrong_secret() -> None:
    """verify_oauth_state raises ValueError if verified with the wrong secret."""
    state = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)

    with pytest.raises(ValueError):
        verify_oauth_state(state=state, secret="wrong-secret")


def test_generate_oauth_state_nonce_differs() -> None:
    """Two calls to generate_oauth_state produce different states (random nonce)."""
    state1 = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)
    state2 = generate_oauth_state(tenant_id=_TENANT_ID, secret=_SECRET)
    # Different nonce means different state tokens
    assert state1 != state2
    # Both must still verify correctly
    assert verify_oauth_state(state=state1, secret=_SECRET) == _TENANT_ID
    assert verify_oauth_state(state=state2, secret=_SECRET) == _TENANT_ID
