"""E2E test fixtures.

Provides fixtures for starting real LangBot process with minimal configuration.
"""

from __future__ import annotations

import pytest
import tempfile
import shutil
import logging
from pathlib import Path

from tests.e2e.utils.config_factory import create_minimal_config, create_test_directories
from tests.e2e.utils.process_manager import LangBotProcess, find_project_root

logger = logging.getLogger(__name__)

pytestmark = pytest.mark.e2e


@pytest.fixture(scope='session')
def e2e_port():
    """Port for E2E testing (non-default to avoid conflicts)."""
    return 15300


@pytest.fixture(scope='session')
def e2e_tmpdir():
    """Create temporary directory for E2E testing."""
    tmpdir = Path(tempfile.mkdtemp(prefix='langbot_e2e_'))
    logger.info(f'E2E tmpdir: {tmpdir}')

    yield tmpdir

    # Cleanup
    logger.info(f'Cleaning up E2E tmpdir: {tmpdir}')
    shutil.rmtree(tmpdir, ignore_errors=True)


@pytest.fixture(scope='session')
def e2e_config_path(e2e_tmpdir, e2e_port):
    """Create minimal config.yaml for E2E testing."""
    config_path = create_minimal_config(e2e_tmpdir, port=e2e_port)
    create_test_directories(e2e_tmpdir)
    logger.info(f'E2E config: {config_path}')
    return config_path


@pytest.fixture(scope='session')
def langbot_process(e2e_config_path, e2e_port, e2e_tmpdir):
    """Start real LangBot process for E2E testing.

    This fixture starts LangBot once per session and reuses it for all tests.
    Coverage data is collected from the subprocess.
    """
    project_root = find_project_root()
    collect_coverage = True

    proc = LangBotProcess(
        project_root=project_root,
        work_dir=e2e_tmpdir,  # Run in tmpdir where data/config.yaml exists
        port=e2e_port,
        timeout=60,  # Longer timeout for first startup
        collect_coverage=collect_coverage,
    )

    success = proc.start()
    if not success:
        stdout, stderr = proc.get_logs()
        pytest.fail(f'LangBot failed to start:\nstdout: {stdout}\nstderr: {stderr}')

    yield proc

    # Cleanup
    proc.stop()

    # Combine coverage data if collected
    if collect_coverage and proc.get_coverage_file():
        coverage_file = proc.get_coverage_file()
        if coverage_file.exists():
            # Copy coverage data to project root for combining
            target = project_root / '.coverage.e2e'
            shutil.copy(coverage_file, target)
            logger.info(f'Coverage data saved to: {target}')


@pytest.fixture
def e2e_client(e2e_port, langbot_process):
    """HTTP client for E2E testing."""
    import httpx

    base_url = f'http://127.0.0.1:{e2e_port}'

    with httpx.Client(base_url=base_url, timeout=10.0, trust_env=False) as client:
        yield client


@pytest.fixture(scope='session')
def e2e_db_path(e2e_tmpdir):
    """Path to SQLite database file."""
    return e2e_tmpdir / 'data' / 'langbot.db'
