"""
Tests for django_cronjob_utils exceptions.
"""
from django.test import TestCase
from django_cronjob_utils.exceptions import (
    CronJobError,
    TaskNotFoundError,
    ConcurrentExecutionError,
    ValidationError,
)


class CronJobErrorTests(TestCase):
    """Tests for CronJobError base exception."""
    
    def test_cron_job_error(self):
        """Test CronJobError can be raised."""
        with self.assertRaises(CronJobError) as cm:
            raise CronJobError("Test error")
        
        self.assertEqual(str(cm.exception), "Test error")
    
    def test_cron_job_error_inheritance(self):
        """Test CronJobError is an Exception."""
        self.assertTrue(issubclass(CronJobError, Exception))
    
    def test_cron_job_error_no_message(self):
        """Test CronJobError without message."""
        with self.assertRaises(CronJobError):
            raise CronJobError()


class TaskNotFoundErrorTests(TestCase):
    """Tests for TaskNotFoundError."""
    
    def test_task_not_found_error(self):
        """Test TaskNotFoundError with message."""
        with self.assertRaises(TaskNotFoundError) as cm:
            raise TaskNotFoundError("Task 'test-task' not found")
        
        self.assertEqual(str(cm.exception), "Task 'test-task' not found")
    
    def test_task_not_found_error_inheritance(self):
        """Test TaskNotFoundError inherits from CronJobError."""
        self.assertTrue(issubclass(TaskNotFoundError, CronJobError))
    
    def test_task_not_found_error_empty_message(self):
        """Test TaskNotFoundError with empty message."""
        with self.assertRaises(TaskNotFoundError) as cm:
            raise TaskNotFoundError("")
        
        self.assertEqual(str(cm.exception), "")


class ConcurrentExecutionErrorTests(TestCase):
    """Tests for ConcurrentExecutionError."""
    
    def test_concurrent_execution_error(self):
        """Test ConcurrentExecutionError with message."""
        with self.assertRaises(ConcurrentExecutionError) as cm:
            raise ConcurrentExecutionError("Task already running")
        
        self.assertEqual(str(cm.exception), "Task already running")
    
    def test_concurrent_execution_error_inheritance(self):
        """Test ConcurrentExecutionError inherits from CronJobError."""
        self.assertTrue(issubclass(ConcurrentExecutionError, CronJobError))
    
    def test_concurrent_execution_error_detailed_message(self):
        """Test ConcurrentExecutionError with detailed message."""
        message = "Task A001 already running for 2024-01-15 (started at 2024-01-15 10:00:00)"
        with self.assertRaises(ConcurrentExecutionError) as cm:
            raise ConcurrentExecutionError(message)
        
        self.assertIn("A001", str(cm.exception))
        self.assertIn("2024-01-15", str(cm.exception))


class ValidationErrorTests(TestCase):
    """Tests for ValidationError."""
    
    def test_validation_error(self):
        """Test ValidationError with message."""
        with self.assertRaises(ValidationError) as cm:
            raise ValidationError("Invalid execution_date")
        
        self.assertEqual(str(cm.exception), "Invalid execution_date")
    
    def test_validation_error_inheritance(self):
        """Test ValidationError inherits from CronJobError."""
        self.assertTrue(issubclass(ValidationError, CronJobError))
    
    def test_validation_error_field_specific(self):
        """Test ValidationError with field-specific message."""
        message = "execution_date must be a date object, got <class 'str'>"
        with self.assertRaises(ValidationError) as cm:
            raise ValidationError(message)
        
        self.assertIn("execution_date", str(cm.exception))
        self.assertIn("date object", str(cm.exception))
