"""
Pytest Configuration and Shared Fixtures

Provides shared test fixtures for unit and integration tests
"""

import pytest
import tempfile
import shutil
from pathlib import Path
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from fastapi.testclient import TestClient

from src.database.models import Base
from src.core.storage import LocalStorage
from config.settings import settings


# =============================================================================
# DATABASE FIXTURES
# =============================================================================

@pytest.fixture(scope="session")
def test_db_engine():
    """
    Create test database engine

    Uses in-memory SQLite for fast tests
    """
    # Use SQLite in-memory for tests
    engine = create_engine("sqlite:///:memory:", echo=False)

    # Create all tables
    Base.metadata.create_all(engine)

    yield engine

    # Cleanup
    Base.metadata.drop_all(engine)
    engine.dispose()


@pytest.fixture
def db_session(test_db_engine):
    """
    Database session fixture

    Creates a new session for each test and rolls back after
    """
    Session = sessionmaker(bind=test_db_engine)
    session = Session()

    yield session

    session.rollback()
    session.close()


# =============================================================================
# STORAGE FIXTURES
# =============================================================================

@pytest.fixture
def temp_storage_dir():
    """
    Temporary storage directory

    Creates a temp dir and cleans up after test
    """
    temp_dir = tempfile.mkdtemp(prefix="giglez_test_")

    yield Path(temp_dir)

    # Cleanup
    shutil.rmtree(temp_dir, ignore_errors=True)


@pytest.fixture
def test_storage(temp_storage_dir):
    """
    Test storage backend (LocalStorage)

    Uses temporary directory
    """
    return LocalStorage(base_path=str(temp_storage_dir))


# =============================================================================
# API FIXTURES
# =============================================================================

@pytest.fixture
def test_client():
    """
    FastAPI test client

    Provides TestClient for API endpoint testing
    """
    from src.api.main import app

    client = TestClient(app)
    return client


# =============================================================================
# SAMPLE DATA FIXTURES
# =============================================================================

@pytest.fixture
def sample_sub_file_key():
    """Sample .sub file content (KEY format)"""
    return """Filetype: Flipper SubGhz Key File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok270Async
Protocol: Princeton
Bit: 24
Key: 00 00 00 00 00 95 D5 D4
TE: 400
"""


@pytest.fixture
def sample_sub_file_raw():
    """Sample .sub file content (RAW format)"""
    return """Filetype: Flipper SubGhz RAW File
Version: 1
Frequency: 315000000
Preset: FuriHalSubGhzPresetOok650Async
Protocol: RAW
RAW_Data: 2980 -240 520 -980 520 -980 1000 -500 480 -1020
"""


@pytest.fixture
def sample_manifest():
    """Sample upload manifest"""
    return {
        "session_uuid": "test-session-001",
        "captures": [
            {
                "filename": "test.sub",
                "latitude": 40.7128,
                "longitude": -74.0060,
                "accuracy": 5.0,
                "altitude": 10.5,
                "timestamp": "2026-01-12T10:00:00Z"
            }
        ]
    }


@pytest.fixture
def sample_gps_coordinates():
    """Sample GPS coordinates (valid)"""
    return [
        (40.7128, -74.0060, 5.0, "NYC"),
        (51.5074, -0.1278, 8.0, "London"),
        (35.6762, 139.6503, 3.0, "Tokyo"),
        (-33.8688, 151.2093, 10.0, "Sydney"),
    ]


@pytest.fixture
def invalid_gps_coordinates():
    """Invalid GPS coordinates for testing"""
    return [
        (91.0, 0.0, 5.0, "Latitude > 90"),
        (-91.0, 0.0, 5.0, "Latitude < -90"),
        (0.0, 181.0, 5.0, "Longitude > 180"),
        (0.0, -181.0, 5.0, "Longitude < -180"),
        (0.0, 0.0, 5.0, "Null Island"),
        (40.7128, -74.0060, 100.0, "Poor accuracy"),
    ]


# =============================================================================
# PYTEST MARKERS
# =============================================================================

def pytest_configure(config):
    """Register custom pytest markers"""
    config.addinivalue_line("markers", "unit: Unit tests (fast, no external dependencies)")
    config.addinivalue_line("markers", "integration: Integration tests (database, API)")
    config.addinivalue_line("markers", "manual: Manual tests (human verification required)")
    config.addinivalue_line("markers", "slow: Slow tests (skip in CI)")
