from dataclasses import replace
from datetime import date
from pathlib import Path

import pandas as pd

from psx_signal.config import DataConfig, load_settings
from psx_signal.data.providers.yahoo_provider import YahooFinanceProvider
from psx_signal.pipelines.yahoo_bootstrap import YahooBootstrapService


def _raw(symbol: str) -> pd.DataFrame:
    base = 1000.0 if symbol == "^KSE" else 100.0
    return pd.DataFrame({
        "Open": [base, base + 1], "High": [base + 2, base + 3],
        "Low": [base - 1, base], "Close": [base + 1, base + 2],
        "Adj Close": [base + 1, base + 2], "Volume": [1000, 1200],
        "Dividends": [0.0, 1.0 if symbol != "^KSE" else 0.0],
        "Stock Splits": [0.0, 0.0],
    }, index=pd.DatetimeIndex(["2026-08-17", "2026-08-18"], name="Date"))


def test_bootstrap_preserves_raw_and_keeps_benchmark_separate(monkeypatch, tmp_path: Path) -> None:
    root = tmp_path / "data"
    candidates = tmp_path / "symbols.csv"
    candidates.write_text("symbol,company_name\nSYS,Systems Limited\n")
    mapping = tmp_path / "map.csv"
    mapping.write_text("psx_symbol,yahoo_symbol,status,verified_at,notes\n")
    base = load_settings()
    data = DataConfig(
        root=str(root), inbox=str(tmp_path / "inbox"), yahoo_symbol_map=str(mapping),
        yahoo_rate_limit_seconds=0, yahoo_retry_backoff_seconds=0,
    )
    settings = replace(base, minimum_history=0, data=data)
    service = YahooBootstrapService(settings)

    def fake_download(symbol, start, end):
        return _raw(symbol), 1

    monkeypatch.setattr(service.provider, "_download_raw", fake_download)
    monkeypatch.chdir(tmp_path)
    result = service.run(date(2026, 8, 17), date(2026, 8, 18), candidates)
    monkeypatch.setattr(
        service.provider, "download_symbol",
        lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("cache should be reused")),
    )
    repeated = service.run(date(2026, 8, 17), date(2026, 8, 18), candidates)
    equities = pd.read_parquet(root / "normalized/equities/eod.parquet")
    benchmark = pd.read_parquet(root / "normalized/indices/KSE100.parquet")
    actions = pd.read_parquet(root / "normalized/corporate_actions.parquet")
    raw_files = list((root / "raw/yahoo").rglob("*.csv"))
    assert result.status == "SUCCESS"
    assert repeated.status == "SUCCESS" and repeated.rows_added == 0
    assert set(equities["symbol"]) == {"SYS"}
    assert set(benchmark["index"]) == {"KSE100"}
    assert set(actions["provider"]) == {"yahoo_finance"}
    assert equities["raw_artifact"].str.startswith("raw/yahoo/equities/").all()
    assert raw_files and all(path.stat().st_mode & 0o222 == 0 for path in raw_files)
