"""Testes para o módulo de segurança."""

import pytest
from src.security.validators import validate_user_data, validate_chat_message, sanitize_input
from src.security.audit import log_security_event, audit_auth_attempt
from marshmallow import ValidationError
import json
import os

def test_validate_user_data_success():
    """Testa validação bem-sucedida de dados de usuário."""
    data = {
        'username': 'testuser123',
        'password': 'TestPass123!'
    }
    result = validate_user_data(data)
    assert result['username'] == 'testuser123'
    assert result['password'] == 'TestPass123!'

def test_validate_user_data_invalid_username():
    """Testa validação de username inválido."""
    data = {
        'username': 'te',  
        'password': 'TestPass123!'
    }
    with pytest.raises(ValidationError):
        validate_user_data(data)

def test_validate_user_data_invalid_password():
    """Testa validação de senha inválida."""
    data = {
        'username': 'testuser123',
        'password': 'weak' 
    }
    with pytest.raises(ValidationError):
        validate_user_data(data)

def test_validate_chat_message_success():
    """Testa validação bem-sucedida de mensagem de chat."""
    data = {
        'message': 'Hello, world!',
        'agent_id': 1
    }
    result = validate_chat_message(data)
    assert result['message'] == 'Hello, world!'
    assert result['agent_id'] == 1

def test_validate_chat_message_invalid():
    """Testa validação de mensagem de chat inválida."""
    data = {
        'message': '<script>alert("xss")</script>',  
        'agent_id': 1
    }
    with pytest.raises(ValidationError):
        validate_chat_message(data)

def test_sanitize_input():
    """Testa sanitização de entrada."""
    input_text = '<script>alert("xss")</script>'
    sanitized = sanitize_input(input_text)
    assert '<script>' not in sanitized
    assert '&lt;script&gt;' in sanitized

def test_sanitize_input_non_string():
    """Testa sanitização de entrada não-string."""
    input_data = 123
    sanitized = sanitize_input(input_data)
    assert sanitized == 123

def test_log_security_event(app, client):
    """Testa registro de evento de segurança."""
    with app.app_context():
        log_security_event('TEST_EVENT', {'test': 'data'})
        assert os.path.exists('logs/security.log')
        with open('logs/security.log', 'r') as f:
            log_content = f.read()
            assert 'TEST_EVENT' in log_content
            assert 'test' in log_content

def test_audit_auth_attempt(app, client):
    """Testa auditoria de tentativa de autenticação."""
    with app.app_context():
        audit_auth_attempt('testuser', True)
        with open('logs/security.log', 'r') as f:
            log_content = f.read()
            assert 'AUTH_ATTEMPT' in log_content
            assert 'testuser' in log_content
            assert 'success' in log_content

def test_rate_limiting(app, client):
    """Testa rate limiting."""
    for _ in range(6):
        response = client.post('/login', json={
            'username': 'testuser',
            'password': 'wrongpass'
        })
    
    assert response.status_code == 429
    assert 'Too Many Requests' in response.json['message']

def test_jwt_authentication(app, client, test_user):
    """Testa autenticação JWT."""
    response = client.post('/login', json={
        'username': 'testuser',
        'password': 'testpass123!'
    })
    assert response.status_code == 200
    assert 'access_token' in response.json['data']
    
    token = response.json['data']['access_token']
    headers = {'Authorization': f'Bearer {token}'}
    response = client.get('/protected-route', headers=headers)
    assert response.status_code == 200

def test_jwt_refresh(app, client, test_user):
    """Testa refresh de token JWT."""
    response = client.post('/login', json={
        'username': 'testuser',
        'password': 'testpass123!'
    })
    refresh_token = response.json['data']['refresh_token']
    headers = {'Authorization': f'Bearer {refresh_token}'}
    response = client.post('/refresh', headers=headers)
    assert response.status_code == 200
    assert 'access_token' in response.json 