"""Integration tests for the .ps1-suffixed script download routes."""
import io
import json
import zipfile

import pytest


# ---------------------------------------------------------------------------
# Fixtures (same pattern as tests/test_packages.py)
# ---------------------------------------------------------------------------


@pytest.fixture
def driver_zip_bytes():
    """Create a minimal valid driver ZIP with a fake INF and CAT file."""
    buf = io.BytesIO()
    with zipfile.ZipFile(buf, "w", compression=zipfile.ZIP_DEFLATED) as zf:
        zf.writestr("printer.inf", "[Version]\nSignature=$WINDOWS NT$\n")
        zf.writestr("printer.cat", "FAKE_CAT")
    return buf.getvalue()


@pytest.fixture
def setup_printer_with_driver(tmp_data_dir, driver_zip_bytes):
    """Create Driver record (with ZIP on disk) and Printer record linked to it."""
    import hashlib
    import os

    import imptune.config as cfg
    from imptune.db.models import Driver, Printer

    sha = hashlib.sha256(driver_zip_bytes).hexdigest()
    drivers_dir = cfg.DRIVERS_DIR
    os.makedirs(drivers_dir, exist_ok=True)
    zip_path = os.path.join(drivers_dir, f"{sha}.zip")
    with open(zip_path, "wb") as f:
        f.write(driver_zip_bytes)

    driver = Driver.create(
        sha256=sha,
        original_filename="printer_driver.zip",
        size_bytes=len(driver_zip_bytes),
        driver_desc=json.dumps(["HP LaserJet Pro"]),
        inf_filename="printer.inf",
    )
    printer = Printer.create(
        name="Test Printer",
        ip_address="192.168.1.100",
        port_name="IP_192.168.1.100",
        driver=driver,
        duplex_mode="OneSided",
        color_mode=True,
        paper_size="A4",
        collate=True,
    )
    return printer, driver


@pytest.fixture
def printer_no_driver(tmp_data_dir):
    """Create Printer record with no driver assigned."""
    from imptune.db.models import Printer

    return Printer.create(
        name="No Driver Printer",
        ip_address="10.0.0.1",
        port_name="IP_10.0.0.1",
        driver=None,
    )


# ---------------------------------------------------------------------------
# .ps1 route tests
# ---------------------------------------------------------------------------


class TestPs1Routes:
    def test_install_ps1_route(self, client, setup_printer_with_driver):
        """GET /printers/{id}/scripts/install.ps1 returns 200 with attachment and PowerShell content."""
        printer, _ = setup_printer_with_driver
        resp = client.get(f"/printers/{printer.id}/scripts/install.ps1")
        assert resp.status_code == 200
        assert 'attachment' in resp.headers["content-disposition"]
        assert 'filename="install.ps1"' in resp.headers["content-disposition"]
        body = resp.text
        assert len(body) > 0
        assert "Add-Printer" in body or "$PSScriptRoot" in body

    def test_uninstall_ps1_route(self, client, setup_printer_with_driver):
        """GET /printers/{id}/scripts/uninstall.ps1 returns 200 with attachment and uninstall content."""
        printer, _ = setup_printer_with_driver
        resp = client.get(f"/printers/{printer.id}/scripts/uninstall.ps1")
        assert resp.status_code == 200
        assert 'attachment' in resp.headers["content-disposition"]
        assert 'filename="uninstall.ps1"' in resp.headers["content-disposition"]
        body = resp.text
        assert len(body) > 0
        assert "Remove-Printer" in body

    def test_detect_ps1_route(self, client, setup_printer_with_driver):
        """GET /printers/{id}/scripts/detect.ps1 returns 200 with attachment and detect content."""
        printer, _ = setup_printer_with_driver
        resp = client.get(f"/printers/{printer.id}/scripts/detect.ps1")
        assert resp.status_code == 200
        assert 'attachment' in resp.headers["content-disposition"]
        assert 'filename="detect.ps1"' in resp.headers["content-disposition"]
        body = resp.text
        assert len(body) > 0
        assert "Get-Printer" in body

    def test_ps1_routes_missing_printer(self, client, tmp_data_dir):
        """GET for non-existent printer returns 404."""
        resp = client.get("/printers/99999/scripts/install.ps1")
        assert resp.status_code == 404

    def test_ps1_routes_no_driver(self, client, printer_no_driver):
        """GET for printer without driver returns 422."""
        resp = client.get(f"/printers/{printer_no_driver.id}/scripts/install.ps1")
        assert resp.status_code == 422
