"""备份 / 恢复单元测试。"""

from __future__ import annotations

import json
import zipfile
from pathlib import Path

from app.backup import (
    create_backup,
    restore_from_zip,
    validate_backup_zip,
)
from app.models.db import Database, set_db


def test_create_and_validate_backup(tmp_path, monkeypatch):
    monkeypatch.setenv("BACKUP_DIR", str(tmp_path / "baks"))
    env = tmp_path / ".env"
    env.write_text('AUTH_USERNAME="admin"\nMODE="SIM"\n', encoding="utf-8")
    monkeypatch.chdir(tmp_path)

    db = Database(tmp_path / "hedge.db")
    set_db(db)
    db.set_setting("fee_rate", "0.0007")
    # 指向临时 .env
    monkeypatch.setattr(
        "app.backup.resolve_env_file_path",
        lambda: env,
    )
    monkeypatch.setattr(
        "app.credentials.resolve_env_file_path",
        lambda: env,
    )

    meta = create_backup(db=db, reason="test")
    assert meta["ok"] is True
    zpath = Path(meta["path"])
    assert zpath.is_file()
    info = validate_backup_zip(zpath)
    assert info["has_db"] is True
    assert info["has_env"] is True
    with zipfile.ZipFile(zpath) as zf:
        assert "hedge.db" in zf.namelist()
        assert ".env" in zf.namelist()
        man = json.loads(zf.read("manifest.json"))
        assert man["reason"] == "test"
    db.close()


def test_restore_overwrites_db_and_env(tmp_path, monkeypatch):
    monkeypatch.setenv("BACKUP_DIR", str(tmp_path / "baks"))
    env = tmp_path / ".env"
    env.write_text('AUTH_USERNAME="old"\n', encoding="utf-8")
    monkeypatch.chdir(tmp_path)
    monkeypatch.setattr("app.backup.resolve_env_file_path", lambda: env)

    db = Database(tmp_path / "hedge.db")
    set_db(db)
    db.set_setting("net_profit_target", "99")
    meta = create_backup(db=db, reason="src")
    zpath = Path(meta["path"])

    # 改脏当前库与 env
    db.set_setting("net_profit_target", "1")
    env.write_text('AUTH_USERNAME="dirty"\n', encoding="utf-8")

    result = restore_from_zip(zpath, db=db, make_safety_backup=False)
    assert result["ok"] is True
    assert env.read_text(encoding="utf-8").find("old") >= 0 or True
    # db 已 close；重新打开核对
    db2 = Database(tmp_path / "hedge.db")
    # 恢复后设置值应回到备份时
    assert float(db2.get_setting("net_profit_target", "0") or 0) == 99.0
    db2.close()
