"""Shared test fixtures."""

import os

import pandas as pd
import pytest
from pathlib import Path

SAMPLES_DIR = Path(__file__).parent.parent / "samples"


# ---------------------------------------------------------------------------
# License gating bypass
# ---------------------------------------------------------------------------
#
# Every CLI entry point and every GUI page now requires a valid license,
# but the test suite shouldn't be in the business of paying for or
# generating licenses on every run. The session-scoped autouse fixture
# below sets the dev-mode env var BEFORE any test code (including
# parametrize-time imports) runs, so all 1900+ existing tests continue
# to pass.
#
# Individual license tests that DO want to exercise the real activation
# flow either:
# - clear the env var themselves and point the manager at a tmp file, or
# - use the explicit ``activated_license_manager`` / ``unactivated_license_manager``
#   fixtures defined below.

@pytest.fixture(scope="session", autouse=True)
def _enable_license_dev_mode():
    """Bypass license checks for every test by default.

    Set in the env so subprocess-based tests (test_install, test_e2e)
    inherit it without each test needing to plumb the env var.
    """
    previous = os.environ.get("DATATOOLS_DEV_MODE")
    os.environ["DATATOOLS_DEV_MODE"] = "1"
    try:
        yield
    finally:
        if previous is None:
            os.environ.pop("DATATOOLS_DEV_MODE", None)
        else:
            os.environ["DATATOOLS_DEV_MODE"] = previous


@pytest.fixture
def isolated_license_path(tmp_path, monkeypatch):
    """Point the license manager at a fresh tmp file for one test.

    Useful when a test wants to exercise the real activation flow:
    create + sign + verify the license bytes in a controlled location
    without polluting ``~/.datatools/license.json``.

    Also clears the dev-mode bypass so the manager actually consults
    the file.
    """
    path = tmp_path / "license.json"
    monkeypatch.setenv("DATATOOLS_LICENSE_PATH", str(path))
    monkeypatch.delenv("DATATOOLS_DEV_MODE", raising=False)
    # The manager singleton caches its handle across tests; drop it
    # so the new env vars take effect.
    from src.license.manager import reset_singleton_for_tests
    reset_singleton_for_tests()
    yield path
    reset_singleton_for_tests()


@pytest.fixture
def activated_license_manager(isolated_license_path):
    """Yield a LicenseManager pointed at a tmp file, pre-activated as
    a Core user. The license is freshly signed with the current
    secret so verification succeeds.
    """
    from src.license import LicenseManager, Tier
    mgr = LicenseManager()
    mgr._mint(name="Test User", email="test@example.com", tier=Tier.CORE)
    return mgr


@pytest.fixture
def unactivated_license_manager(isolated_license_path):
    """Yield a LicenseManager pointed at a tmp file with NO license
    file. Useful for testing the activation flow + gate behaviour.
    """
    from src.license import LicenseManager
    return LicenseManager()


@pytest.fixture
def sample_csv_path():
    return SAMPLES_DIR / "messy_sales.csv"


@pytest.fixture
def sample_df(sample_csv_path):
    return pd.read_csv(sample_csv_path, dtype=str, keep_default_na=False)


@pytest.fixture
def simple_df():
    """Small DataFrame with obvious duplicates for unit testing."""
    return pd.DataFrame({
        "name": ["Alice", "alice", "Bob", "Charlie", "ALICE"],
        "email": ["alice@test.com", "alice@test.com", "bob@test.com",
                  "charlie@test.com", "alice@test.com"],
        "phone": ["555-1234", "555-1234", "555-5678", "555-9012", "555-1234"],
    })


@pytest.fixture
def merge_df():
    """DataFrame with partial records that benefit from merge."""
    return pd.DataFrame({
        "name": ["John Doe", "John Doe", "Jane Smith"],
        "email": ["john@test.com", "john@test.com", "jane@test.com"],
        "phone": ["555-1111", "", "555-3333"],
        "address": ["", "123 Main St", "456 Oak Ave"],
    })


@pytest.fixture
def tmp_csv(tmp_path, simple_df):
    """Write simple_df to a temp CSV and return the path."""
    path = tmp_path / "test_input.csv"
    simple_df.to_csv(path, index=False)
    return path
