# -*- coding: utf-8 -*-
"""
Analytics Tests
==============

Comprehensive test suite for the Adtlas Analytics module.
Provides unit tests, integration tests, and performance tests
for all analytics functionality.

Test Categories:
- Model Tests: Analytics data models validation
- API Tests: REST API endpoint testing
- View Tests: View functionality and permissions
- Serializer Tests: Data serialization validation
- Integration Tests: Cross-module functionality
- Performance Tests: Load and stress testing
- Security Tests: Authentication and authorization
- Data Quality Tests: Analytics data validation

Test Features:
- Comprehensive coverage
- Mock data generation
- Performance benchmarking
- Security validation
- API endpoint testing
- Database integrity checks
- Real-time data simulation
- Export functionality testing

Test Data:
- Factory-generated test data
- Realistic analytics scenarios
- Edge case coverage
- Performance test datasets
- Security test cases

Author: Adtlas Development Team
Version: 1.0.0
Last Updated: 2024
"""

import json
import tempfile
from datetime import datetime, timedelta, date
from decimal import Decimal
from unittest.mock import patch, Mock, MagicMock

from django.test import TestCase, TransactionTestCase, override_settings
from django.urls import reverse
from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import SimpleUploadedFile
from django.utils import timezone
from django.db import transaction
from django.test.utils import override_settings
from django.core.cache import cache
from django.conf import settings

from rest_framework.test import APITestCase, APIClient
from rest_framework import status
from rest_framework.authtoken.models import Token

from apps.campaigns.models import Campaign
from apps.channels.models import Channel
from apps.advertisers.models import Brand
from apps.core.models import User

from .models import (
    SfrAnalytics,
    BouyguesAnalytics,
    Impression,
    VastResponse,
    PerformanceMetric,
    AnalyticsReport
)
from .serializers import (
    SfrAnalyticsSerializer,
    BouyguesAnalyticsSerializer,
    ImpressionSerializer,
    VastResponseSerializer,
    PerformanceMetricSerializer,
    AnalyticsReportSerializer
)


class AnalyticsModelTestCase(TestCase):
    """
    Test cases for Analytics models.
    
    Tests model creation, validation, relationships,
    and custom methods for all analytics models.
    
    Test Coverage:
    - Model field validation
    - Relationship integrity
    - Custom method functionality
    - Model constraints
    - Data integrity
    """
    
    def setUp(self):
        """
        Set up test data for analytics model tests.
        
        Creates test instances of related models:
        - User accounts
        - Advertisers
        - Campaigns
        - Channels
        - Analytics data
        """
        # Create test user
        self.user = get_user_model().objects.create_user(
            username='testuser',
            email='test@example.com',
            password='testpass123'
        )
        
        # Create test advertiser
        self.advertiser = Advertiser.objects.create(
            name='Test Advertiser',
            email='advertiser@test.com',
            phone='+1234567890',
            is_active=True
        )
        
        # Create test channel
        self.channel = Channel.objects.create(
            name='Test Channel',
            code='TEST_CH',
            description='Test channel for analytics',
            is_active=True
        )
        
        # Create test campaign
        self.campaign = Campaign.objects.create(
            name='Test Campaign',
            advertiser=self.advertiser,
            start_date=date.today(),
            end_date=date.today() + timedelta(days=30),
            budget=Decimal('10000.00'),
            status='active'
        )
    
    def test_sfr_analytics_creation(self):
        """
        Test SFR Analytics model creation and validation.
        
        Validates:
        - Model instance creation
        - Field value assignment
        - Relationship integrity
        - Custom method functionality
        """
        sfr_analytics = SfrAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=12,
            audience_count=1000,
            market_share=Decimal('15.5'),
            rating=Decimal('4.2'),
            reach=Decimal('25.0'),
            frequency=Decimal('2.1'),
            duration=1800,
            demographics={'age_18_34': 45, 'age_35_54': 35, 'age_55_plus': 20},
            geographic_data={'urban': 60, 'suburban': 30, 'rural': 10}
        )
        
        # Test model creation
        self.assertIsNotNone(sfr_analytics.id)
        self.assertEqual(sfr_analytics.channel, self.channel)
        self.assertEqual(sfr_analytics.campaign, self.campaign)
        self.assertEqual(sfr_analytics.audience_count, 1000)
        self.assertEqual(sfr_analytics.market_share, Decimal('15.5'))
        
        # Test custom methods
        performance_score = sfr_analytics.get_performance_score()
        self.assertIsInstance(performance_score, float)
        self.assertGreater(performance_score, 0)
        
        # Test string representation
        str_repr = str(sfr_analytics)
        self.assertIn('Test Channel', str_repr)
        self.assertIn(str(date.today()), str_repr)
    
    def test_bouygues_analytics_creation(self):
        """
        Test Bouygues Analytics model creation and validation.
        
        Validates:
        - Model instance creation
        - Provider-specific fields
        - Data validation
        - Custom calculations
        """
        bouygues_analytics = BouyguesAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=14,
            viewers=1500,
            share=Decimal('18.2'),
            rating_value=Decimal('3.8'),
            reach_percentage=Decimal('22.5'),
            avg_frequency=Decimal('1.9'),
            watch_time=1650,
            device_data={'tv': 70, 'mobile': 20, 'tablet': 10},
            age_groups={'18_34': 40, '35_54': 35, '55_plus': 25}
        )
        
        # Test model creation
        self.assertIsNotNone(bouygues_analytics.id)
        self.assertEqual(bouygues_analytics.viewers, 1500)
        self.assertEqual(bouygues_analytics.share, Decimal('18.2'))
        
        # Test custom methods
        engagement_score = bouygues_analytics.get_engagement_score()
        self.assertIsInstance(engagement_score, float)
        
        # Test data validation
        self.assertTrue(bouygues_analytics.is_valid_data())
    
    def test_impression_creation(self):
        """
        Test Impression model creation and tracking.
        
        Validates:
        - Impression tracking data
        - Performance metrics
        - Geographic information
        - Device information
        """
        impression = Impression.objects.create(
            campaign=self.campaign,
            channel=self.channel,
            timestamp=timezone.now(),
            duration=30,
            completion_rate=Decimal('85.5'),
            click_through=True,
            geographic_info={'country': 'France', 'region': 'Ile-de-France'},
            device_info={'type': 'mobile', 'os': 'iOS', 'browser': 'Safari'}
        )
        
        # Test model creation
        self.assertIsNotNone(impression.id)
        self.assertEqual(impression.campaign, self.campaign)
        self.assertTrue(impression.click_through)
        self.assertEqual(impression.completion_rate, Decimal('85.5'))
        
        # Test viewability calculation
        self.assertTrue(impression.is_viewable)
        
        # Test performance metrics
        self.assertGreater(impression.completion_rate, 50)
    
    def test_vast_response_creation(self):
        """
        Test VAST Response model creation and validation.
        
        Validates:
        - VAST response tracking
        - Performance metrics
        - Error handling
        - Response analysis
        """
        vast_response = VastResponse.objects.create(
            campaign=self.campaign,
            vast_url='https://example.com/vast.xml',
            served_at=timezone.now(),
            response_time=150,
            status_code=200,
            xml_content='<VAST version="3.0">...</VAST>',
            tracking_urls=['https://track1.com', 'https://track2.com'],
            creative_info={'duration': 30, 'type': 'video'}
        )
        
        # Test model creation
        self.assertIsNotNone(vast_response.id)
        self.assertEqual(vast_response.status_code, 200)
        self.assertEqual(vast_response.response_time, 150)
        
        # Test success validation
        self.assertTrue(vast_response.is_successful)
        
        # Test performance validation
        self.assertTrue(vast_response.is_fast_response)
    
    def test_performance_metric_creation(self):
        """
        Test Performance Metric model creation and calculations.
        
        Validates:
        - Performance metric tracking
        - Financial calculations
        - ROI computation
        - Metric aggregation
        """
        performance_metric = PerformanceMetric.objects.create(
            campaign=self.campaign,
            channel=self.channel,
            date=date.today(),
            metric_type='daily',
            impressions_count=5000,
            clicks_count=150,
            completion_rate=Decimal('78.5'),
            ctr=Decimal('3.0'),
            cpm=Decimal('2.50'),
            revenue=Decimal('12500.00'),
            cost=Decimal('10000.00'),
            roi=Decimal('25.0')
        )
        
        # Test model creation
        self.assertIsNotNone(performance_metric.id)
        self.assertEqual(performance_metric.impressions_count, 5000)
        self.assertEqual(performance_metric.clicks_count, 150)
        
        # Test calculated fields
        calculated_ctr = performance_metric.calculate_ctr()
        self.assertAlmostEqual(float(calculated_ctr), 3.0, places=1)
        
        # Test ROI calculation
        calculated_roi = performance_metric.calculate_roi()
        self.assertAlmostEqual(float(calculated_roi), 25.0, places=1)
    
    def test_analytics_report_creation(self):
        """
        Test Analytics Report model creation and management.
        
        Validates:
        - Report generation
        - File management
        - Expiration handling
        - Access control
        """
        analytics_report = AnalyticsReport.objects.create(
            name='Test Analytics Report',
            report_type='campaign_performance',
            generated_by=self.user,
            parameters={'campaign_id': self.campaign.id, 'date_range': '30_days'},
            file_path='/reports/test_report.pdf',
            file_size=1024000,
            expires_at=timezone.now() + timedelta(days=7),
            is_public=False
        )
        
        # Test model creation
        self.assertIsNotNone(analytics_report.id)
        self.assertEqual(analytics_report.name, 'Test Analytics Report')
        self.assertEqual(analytics_report.generated_by, self.user)
        
        # Test expiration check
        self.assertFalse(analytics_report.is_expired)
        
        # Test file size formatting
        formatted_size = analytics_report.get_formatted_file_size()
        self.assertIn('MB', formatted_size)


class AnalyticsAPITestCase(APITestCase):
    """
    Test cases for Analytics API endpoints.
    
    Tests REST API functionality including:
    - Authentication and authorization
    - CRUD operations
    - Filtering and pagination
    - Data validation
    - Error handling
    
    Test Coverage:
    - All API endpoints
    - HTTP methods (GET, POST, PUT, DELETE)
    - Authentication requirements
    - Permission checks
    - Data validation
    - Error responses
    """
    
    def setUp(self):
        """
        Set up test data for API tests.
        
        Creates:
        - Test users with different permissions
        - Authentication tokens
        - Test data for API operations
        - API client configuration
        """
        # Create test users
        self.admin_user = get_user_model().objects.create_user(
            username='admin',
            email='admin@test.com',
            password='adminpass123',
            is_staff=True,
            is_superuser=True
        )
        
        self.regular_user = get_user_model().objects.create_user(
            username='user',
            email='user@test.com',
            password='userpass123'
        )
        
        # Create authentication tokens
        self.admin_token = Token.objects.create(user=self.admin_user)
        self.user_token = Token.objects.create(user=self.regular_user)
        
        # Set up API client
        self.client = APIClient()
        
        # Create test data
        self.advertiser = Advertiser.objects.create(
            name='API Test Advertiser',
            email='api@test.com',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='API Test Channel',
            code='API_CH',
            is_active=True
        )
        
        self.campaign = Campaign.objects.create(
            name='API Test Campaign',
            advertiser=self.advertiser,
            start_date=date.today(),
            end_date=date.today() + timedelta(days=30),
            budget=Decimal('5000.00'),
            status='active'
        )
    
    def test_sfr_analytics_api_list(self):
        """
        Test SFR Analytics API list endpoint.
        
        Validates:
        - Authentication requirement
        - Data retrieval
        - Filtering capabilities
        - Pagination
        """
        # Create test data
        SfrAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=10,
            audience_count=1000,
            market_share=Decimal('15.0'),
            rating=Decimal('4.0')
        )
        
        # Test unauthenticated access
        url = reverse('analytics:sfr-analytics-list')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        
        # Test authenticated access
        self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.admin_token.key}')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 1)
        
        # Test filtering
        response = self.client.get(url, {'channel': self.channel.id})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 1)
    
    def test_sfr_analytics_api_create(self):
        """
        Test SFR Analytics API create endpoint.
        
        Validates:
        - Data creation
        - Validation rules
        - Permission requirements
        - Error handling
        """
        url = reverse('analytics:sfr-analytics-list')
        data = {
            'channel': self.channel.id,
            'campaign': self.campaign.id,
            'date': date.today().isoformat(),
            'hour': 12,
            'audience_count': 1500,
            'market_share': '18.5',
            'rating': '4.2',
            'reach': '25.0',
            'frequency': '2.0',
            'duration': 1800
        }
        
        # Test with admin user
        self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.admin_token.key}')
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        
        # Verify data creation
        sfr_analytics = SfrAnalytics.objects.get(id=response.data['id'])
        self.assertEqual(sfr_analytics.audience_count, 1500)
        self.assertEqual(float(sfr_analytics.market_share), 18.5)
    
    def test_impression_api_operations(self):
        """
        Test Impression API CRUD operations.
        
        Validates:
        - Create, read, update, delete operations
        - Data validation
        - Permission checks
        - Error handling
        """
        # Create impression
        url = reverse('analytics:impressions-list')
        data = {
            'campaign': self.campaign.id,
            'channel': self.channel.id,
            'timestamp': timezone.now().isoformat(),
            'duration': 30,
            'completion_rate': '85.0',
            'click_through': True
        }
        
        self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.admin_token.key}')
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        
        impression_id = response.data['id']
        
        # Test retrieve
        detail_url = reverse('analytics:impressions-detail', args=[impression_id])
        response = self.client.get(detail_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['duration'], 30)
        
        # Test update
        update_data = {'duration': 45}
        response = self.client.patch(detail_url, update_data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['duration'], 45)
        
        # Test delete
        response = self.client.delete(detail_url)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
    
    def test_analytics_dashboard_api(self):
        """
        Test Analytics Dashboard API endpoint.
        
        Validates:
        - Dashboard data aggregation
        - Real-time metrics
        - Performance indicators
        - Caching behavior
        """
        # Create test analytics data
        SfrAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=10,
            audience_count=1000,
            market_share=Decimal('15.0'),
            rating=Decimal('4.0')
        )
        
        Impression.objects.create(
            campaign=self.campaign,
            channel=self.channel,
            timestamp=timezone.now(),
            duration=30,
            completion_rate=Decimal('80.0')
        )
        
        # Test dashboard endpoint
        url = reverse('analytics:dashboard')
        self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.admin_token.key}')
        response = self.client.get(url)
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertIn('total_impressions', response.data)
        self.assertIn('average_completion_rate', response.data)
        self.assertIn('top_channels', response.data)
    
    def test_analytics_export_api(self):
        """
        Test Analytics Export API endpoint.
        
        Validates:
        - Data export functionality
        - Format support (CSV, JSON, PDF)
        - Filtering options
        - File generation
        """
        # Create test data
        SfrAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=10,
            audience_count=1000,
            market_share=Decimal('15.0'),
            rating=Decimal('4.0')
        )
        
        # Test CSV export
        url = reverse('analytics:data-export')
        params = {
            'format': 'csv',
            'model': 'sfr_analytics',
            'date_from': date.today().isoformat(),
            'date_to': date.today().isoformat()
        }
        
        self.client.credentials(HTTP_AUTHORIZATION=f'Token {self.admin_token.key}')
        response = self.client.get(url, params)
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response['Content-Type'], 'text/csv')
        
        # Test JSON export
        params['format'] = 'json'
        response = self.client.get(url, params)
        
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response['Content-Type'], 'application/json')


class AnalyticsPerformanceTestCase(TransactionTestCase):
    """
    Performance test cases for Analytics module.
    
    Tests system performance under various load conditions:
    - High-volume data processing
    - Concurrent user access
    - Database query optimization
    - API response times
    - Memory usage
    
    Test Scenarios:
    - Bulk data insertion
    - Complex aggregation queries
    - Real-time data processing
    - Export operations
    - Dashboard loading
    """
    
    def setUp(self):
        """
        Set up performance test environment.
        
        Creates:
        - Large datasets for testing
        - Performance monitoring tools
        - Benchmark baselines
        """
        self.user = get_user_model().objects.create_user(
            username='perfuser',
            email='perf@test.com',
            password='perfpass123'
        )
        
        self.advertiser = Advertiser.objects.create(
            name='Performance Test Advertiser',
            email='perf@test.com',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Performance Test Channel',
            code='PERF_CH',
            is_active=True
        )
        
        self.campaign = Campaign.objects.create(
            name='Performance Test Campaign',
            advertiser=self.advertiser,
            start_date=date.today(),
            end_date=date.today() + timedelta(days=30),
            budget=Decimal('10000.00'),
            status='active'
        )
    
    def test_bulk_analytics_creation(self):
        """
        Test bulk creation of analytics records.
        
        Validates:
        - Large dataset handling
        - Database performance
        - Memory usage
        - Transaction management
        """
        import time
        
        # Create 1000 analytics records
        start_time = time.time()
        
        analytics_data = []
        for i in range(1000):
            analytics_data.append(
                SfrAnalytics(
                    channel=self.channel,
                    campaign=self.campaign,
                    date=date.today(),
                    hour=i % 24,
                    audience_count=1000 + i,
                    market_share=Decimal('15.0') + (i % 10),
                    rating=Decimal('4.0') + (i % 5) * Decimal('0.1')
                )
            )
        
        with transaction.atomic():
            SfrAnalytics.objects.bulk_create(analytics_data)
        
        end_time = time.time()
        creation_time = end_time - start_time
        
        # Verify creation
        self.assertEqual(SfrAnalytics.objects.count(), 1000)
        
        # Performance assertion (should complete within 5 seconds)
        self.assertLess(creation_time, 5.0)
    
    def test_complex_aggregation_performance(self):
        """
        Test performance of complex aggregation queries.
        
        Validates:
        - Query optimization
        - Aggregation performance
        - Index usage
        - Response times
        """
        import time
        from django.db.models import Avg, Sum, Count
        
        # Create test data
        for i in range(100):
            SfrAnalytics.objects.create(
                channel=self.channel,
                campaign=self.campaign,
                date=date.today(),
                hour=i % 24,
                audience_count=1000 + i,
                market_share=Decimal('15.0'),
                rating=Decimal('4.0')
            )
        
        # Test complex aggregation
        start_time = time.time()
        
        result = SfrAnalytics.objects.filter(
            date=date.today()
        ).aggregate(
            avg_audience=Avg('audience_count'),
            total_audience=Sum('audience_count'),
            record_count=Count('id'),
            avg_rating=Avg('rating')
        )
        
        end_time = time.time()
        query_time = end_time - start_time
        
        # Verify results
        self.assertIsNotNone(result['avg_audience'])
        self.assertEqual(result['record_count'], 100)
        
        # Performance assertion (should complete within 1 second)
        self.assertLess(query_time, 1.0)
    
    @patch('apps.analytics.tasks.generate_analytics_report')
    def test_report_generation_performance(self, mock_task):
        """
        Test performance of report generation.
        
        Validates:
        - Report generation speed
        - Memory usage during generation
        - File I/O performance
        - Task queue performance
        """
        import time
        
        # Mock successful task execution
        mock_task.delay.return_value = Mock(id='test-task-id')
        
        # Create test data
        for i in range(50):
            PerformanceMetric.objects.create(
                campaign=self.campaign,
                channel=self.channel,
                date=date.today(),
                metric_type='daily',
                impressions_count=1000 + i,
                clicks_count=50 + i,
                ctr=Decimal('5.0'),
                revenue=Decimal('1000.00')
            )
        
        # Test report generation
        start_time = time.time()
        
        report = AnalyticsReport.objects.create(
            name='Performance Test Report',
            report_type='performance_summary',
            generated_by=self.user,
            parameters={'campaign_id': self.campaign.id}
        )
        
        end_time = time.time()
        generation_time = end_time - start_time
        
        # Verify report creation
        self.assertIsNotNone(report.id)
        
        # Performance assertion (should complete within 2 seconds)
        self.assertLess(generation_time, 2.0)


class AnalyticsIntegrationTestCase(TestCase):
    """
    Integration test cases for Analytics module.
    
    Tests integration with other modules and external services:
    - Campaign integration
    - Channel integration
    - User authentication integration
    - External API integration
    - Real-time data processing
    
    Test Coverage:
    - Cross-module functionality
    - Data consistency
    - Event handling
    - Signal processing
    - Cache integration
    """
    
    def setUp(self):
        """
        Set up integration test environment.
        
        Creates:
        - Multi-module test data
        - Integration points
        - Mock external services
        """
        self.user = get_user_model().objects.create_user(
            username='integuser',
            email='integ@test.com',
            password='integpass123'
        )
        
        self.advertiser = Advertiser.objects.create(
            name='Integration Test Advertiser',
            email='integ@test.com',
            is_active=True
        )
        
        self.channel = Channel.objects.create(
            name='Integration Test Channel',
            code='INTEG_CH',
            is_active=True
        )
        
        self.campaign = Campaign.objects.create(
            name='Integration Test Campaign',
            advertiser=self.advertiser,
            start_date=date.today(),
            end_date=date.today() + timedelta(days=30),
            budget=Decimal('15000.00'),
            status='active'
        )
    
    def test_campaign_analytics_integration(self):
        """
        Test integration between campaigns and analytics.
        
        Validates:
        - Campaign performance tracking
        - Analytics data association
        - Metric calculation
        - Report generation
        """
        # Create analytics data for campaign
        impression = Impression.objects.create(
            campaign=self.campaign,
            channel=self.channel,
            timestamp=timezone.now(),
            duration=30,
            completion_rate=Decimal('85.0'),
            click_through=True
        )
        
        performance_metric = PerformanceMetric.objects.create(
            campaign=self.campaign,
            channel=self.channel,
            date=date.today(),
            metric_type='daily',
            impressions_count=1000,
            clicks_count=85,
            ctr=Decimal('8.5'),
            revenue=Decimal('2500.00')
        )
        
        # Test campaign analytics retrieval
        campaign_impressions = Impression.objects.filter(campaign=self.campaign)
        self.assertEqual(campaign_impressions.count(), 1)
        
        campaign_metrics = PerformanceMetric.objects.filter(campaign=self.campaign)
        self.assertEqual(campaign_metrics.count(), 1)
        
        # Test metric calculations
        total_revenue = campaign_metrics.aggregate(Sum('revenue'))['revenue__sum']
        self.assertEqual(total_revenue, Decimal('2500.00'))
    
    def test_channel_analytics_integration(self):
        """
        Test integration between channels and analytics.
        
        Validates:
        - Channel performance tracking
        - Multi-provider analytics
        - Data aggregation
        - Comparison metrics
        """
        # Create SFR analytics for channel
        sfr_analytics = SfrAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=12,
            audience_count=2000,
            market_share=Decimal('20.0'),
            rating=Decimal('4.5')
        )
        
        # Create Bouygues analytics for channel
        bouygues_analytics = BouyguesAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=12,
            viewers=1800,
            share=Decimal('18.5'),
            rating_value=Decimal('4.2')
        )
        
        # Test channel analytics retrieval
        channel_sfr = SfrAnalytics.objects.filter(channel=self.channel)
        channel_bouygues = BouyguesAnalytics.objects.filter(channel=self.channel)
        
        self.assertEqual(channel_sfr.count(), 1)
        self.assertEqual(channel_bouygues.count(), 1)
        
        # Test cross-provider comparison
        sfr_audience = channel_sfr.first().audience_count
        bouygues_viewers = channel_bouygues.first().viewers
        
        self.assertGreater(sfr_audience, bouygues_viewers)
    
    @override_settings(CACHES={
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        }
    })
    def test_cache_integration(self):
        """
        Test cache integration for analytics data.
        
        Validates:
        - Cache key generation
        - Data caching
        - Cache invalidation
        - Performance improvement
        """
        from django.core.cache import cache
        
        # Clear cache
        cache.clear()
        
        # Create analytics data
        analytics = SfrAnalytics.objects.create(
            channel=self.channel,
            campaign=self.campaign,
            date=date.today(),
            hour=12,
            audience_count=1500,
            market_share=Decimal('17.5'),
            rating=Decimal('4.3')
        )
        
        # Test cache key generation
        cache_key = f'analytics_sfr_{self.channel.id}_{date.today()}'
        
        # Cache analytics data
        cache.set(cache_key, analytics, timeout=300)
        
        # Retrieve from cache
        cached_analytics = cache.get(cache_key)
        self.assertIsNotNone(cached_analytics)
        self.assertEqual(cached_analytics.id, analytics.id)
        
        # Test cache invalidation
        cache.delete(cache_key)
        cached_analytics = cache.get(cache_key)
        self.assertIsNone(cached_analytics)


# Test utilities and helpers
class AnalyticsTestUtils:
    """
    Utility class for analytics testing.
    
    Provides helper methods for:
    - Test data generation
    - Mock object creation
    - Performance measurement
    - Data validation
    
    Helper Methods:
    - create_test_analytics_data()
    - generate_mock_vast_response()
    - measure_performance()
    - validate_analytics_data()
    """
    
    @staticmethod
    def create_test_analytics_data(count=10, channel=None, campaign=None):
        """
        Create test analytics data for testing.
        
        Args:
            count (int): Number of records to create
            channel (Channel): Channel instance
            campaign (Campaign): Campaign instance
            
        Returns:
            list: Created analytics instances
        """
        analytics_data = []
        
        for i in range(count):
            analytics = SfrAnalytics.objects.create(
                channel=channel,
                campaign=campaign,
                date=date.today(),
                hour=i % 24,
                audience_count=1000 + i * 10,
                market_share=Decimal('15.0') + i,
                rating=Decimal('4.0') + (i % 5) * Decimal('0.1')
            )
            analytics_data.append(analytics)
        
        return analytics_data
    
    @staticmethod
    def generate_mock_vast_response():
        """
        Generate mock VAST response data.
        
        Returns:
            dict: Mock VAST response data
        """
        return {
            'vast_url': 'https://example.com/vast.xml',
            'response_time': 120,
            'status_code': 200,
            'xml_content': '<VAST version="3.0"><Ad>...</Ad></VAST>',
            'tracking_urls': [
                'https://track1.example.com',
                'https://track2.example.com'
            ],
            'creative_info': {
                'duration': 30,
                'type': 'video',
                'width': 1920,
                'height': 1080
            }
        }
    
    @staticmethod
    def measure_performance(func, *args, **kwargs):
        """
        Measure function execution performance.
        
        Args:
            func (callable): Function to measure
            *args: Function arguments
            **kwargs: Function keyword arguments
            
        Returns:
            tuple: (result, execution_time)
        """
        import time
        
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        
        execution_time = end_time - start_time
        return result, execution_time
    
    @staticmethod
    def validate_analytics_data(analytics_instance):
        """
        Validate analytics data integrity.
        
        Args:
            analytics_instance: Analytics model instance
            
        Returns:
            bool: True if data is valid
        """
        # Basic validation checks
        if not analytics_instance.id:
            return False
        
        if hasattr(analytics_instance, 'audience_count'):
            if analytics_instance.audience_count < 0:
                return False
        
        if hasattr(analytics_instance, 'market_share'):
            if analytics_instance.market_share < 0 or analytics_instance.market_share > 100:
                return False
        
        if hasattr(analytics_instance, 'rating'):
            if analytics_instance.rating < 0 or analytics_instance.rating > 10:
                return False
        
        return True


# Export test classes for discovery
__all__ = [
    'AnalyticsModelTestCase',
    'AnalyticsAPITestCase',
    'AnalyticsPerformanceTestCase',
    'AnalyticsIntegrationTestCase',
    'AnalyticsTestUtils'
]