"""
Tests basiques Bedrock - PAS besoin d'AWS
"""

import pytest
from pathlib import Path
import json
from kosty.services.bedrock_audit import BedrockAuditService


class TestBedrockServiceBasics:
    """Tests qui n'appellent pas AWS"""
    
    def test_pricing_loads(self):
        """Test que le pricing JSON charge correctement"""
        service = BedrockAuditService()
        
        assert 'bedrock_pricing' in service.pricing_data
        assert len(service.pricing_data['bedrock_pricing']) > 0
        assert 'sagemaker_pricing' in service.pricing_data
    
    def test_pricing_file_exists(self):
        """Test que le fichier pricing existe"""
        pricing_file = Path(__file__).parent.parent / 'data' / 'ai_pricing.json'
        assert pricing_file.exists()
        
        # Vérifier que c'est du JSON valide
        with open(pricing_file, 'r') as f:
            data = json.load(f)
            assert isinstance(data, dict)
    
    def test_token_cost_calculation(self):
        """Test calcul de coût par tokens"""
        service = BedrockAuditService()
        
        # Claude 3.5 Sonnet: $0.003/1K input, $0.015/1K output
        cost = service._calculate_token_cost(
            'anthropic.claude-3-5-sonnet-20241022-v2:0',
            input_tokens=1000,
            output_tokens=1000
        )
        
        expected = (1000/1000 * 0.003) + (1000/1000 * 0.015)  # $0.018
        assert cost == expected
    
    def test_token_cost_calculation_zero_tokens(self):
        """Test avec 0 tokens"""
        service = BedrockAuditService()
        
        cost = service._calculate_token_cost(
            'anthropic.claude-3-5-sonnet-20241022-v2:0',
            input_tokens=0,
            output_tokens=0
        )
        
        assert cost == 0.0
    
    def test_token_cost_calculation_large_numbers(self):
        """Test avec grands nombres de tokens"""
        service = BedrockAuditService()
        
        # 1 million input, 500K output
        cost = service._calculate_token_cost(
            'anthropic.claude-3-5-sonnet-20241022-v2:0',
            input_tokens=1_000_000,
            output_tokens=500_000
        )
        
        expected = (1_000_000/1000 * 0.003) + (500_000/1000 * 0.015)
        assert cost == expected
    
    def test_token_cost_unknown_model(self):
        """Test avec modèle inconnu"""
        service = BedrockAuditService()
        
        cost = service._calculate_token_cost(
            'unknown.model.id',
            input_tokens=1000,
            output_tokens=1000
        )
        
        # Devrait retourner 0 pour modèle inconnu
        assert cost == 0.0
    
    def test_model_name_lookup(self):
        """Test lookup de nom de modèle"""
        service = BedrockAuditService()
        
        name = service._get_model_name('anthropic.claude-3-5-sonnet-20241022-v2:0')
        assert name == 'Claude 3.5 Sonnet'
    
    def test_model_name_lookup_unknown(self):
        """Test lookup modèle inconnu"""
        service = BedrockAuditService()
        
        model_id = 'unknown.model.id'
        name = service._get_model_name(model_id)
        
        # Devrait retourner le model_id si inconnu
        assert name == model_id
    
    def test_all_models_have_pricing(self):
        """Test que tous les modèles ont des prix input et output"""
        service = BedrockAuditService()
        
        for model_id, pricing in service.pricing_data['bedrock_pricing'].items():
            assert 'input_per_1k' in pricing, f"Missing input_per_1k for {model_id}"
            assert 'output_per_1k' in pricing, f"Missing output_per_1k for {model_id}"
            assert 'model_name' in pricing, f"Missing model_name for {model_id}"
            
            # Vérifier que les prix sont des nombres
            assert isinstance(pricing['input_per_1k'], (int, float))
            assert isinstance(pricing['output_per_1k'], (int, float))
            assert pricing['input_per_1k'] >= 0
            assert pricing['output_per_1k'] >= 0
    
    def test_cost_checks_list(self):
        """Test que les listes de checks sont définies"""
        service = BedrockAuditService()
        
        assert hasattr(service, 'cost_checks')
        assert hasattr(service, 'security_checks')
        assert isinstance(service.cost_checks, list)
        assert isinstance(service.security_checks, list)
        assert len(service.cost_checks) > 0
        assert len(service.security_checks) > 0


class TestTokenCostEdgeCases:
    """Tests edge cases pour calcul coûts"""
    
    def test_opus_vs_sonnet_cost_difference(self):
        """Vérifier que Opus est plus cher que Sonnet"""
        service = BedrockAuditService()
        
        opus_cost = service._calculate_token_cost(
            'anthropic.claude-3-opus-20240229-v1:0',
            input_tokens=1000,
            output_tokens=1000
        )
        
        sonnet_cost = service._calculate_token_cost(
            'anthropic.claude-3-5-sonnet-20241022-v2:0',
            input_tokens=1000,
            output_tokens=1000
        )
        
        assert opus_cost > sonnet_cost
    
    def test_haiku_is_cheapest(self):
        """Vérifier que Haiku est le moins cher"""
        service = BedrockAuditService()
        
        haiku_cost = service._calculate_token_cost(
            'anthropic.claude-3-haiku-20240307-v1:0',
            input_tokens=1000,
            output_tokens=1000
        )
        
        sonnet_cost = service._calculate_token_cost(
            'anthropic.claude-3-5-sonnet-20241022-v2:0',
            input_tokens=1000,
            output_tokens=1000
        )
        
        opus_cost = service._calculate_token_cost(
            'anthropic.claude-3-opus-20240229-v1:0',
            input_tokens=1000,
            output_tokens=1000
        )
        
        assert haiku_cost < sonnet_cost < opus_cost