"""Tests for the printer installer batch endpoint (/api/printers/install-batch).

The printer installer map lets a user pick printers on the shopfloor map and
download a .bat that installs them, grouping the same way the classic
installprinter.asp did (HP/Xerox -> universal PrinterInstaller.exe; other
printers with a .exe installpath -> that installer /SILENT; anything else ->
manual).
"""

import pytest


@pytest.fixture
def printer_assettype(db):
    from shopdb.core.models import AssetType
    at = AssetType(assettype='printer', pluginname='printers',
                   tablename='printers', description='Printers')
    db.session.add(at)
    db.session.commit()
    return at


def _vendor(db, name):
    from shopdb.core.models import Vendor
    v = Vendor(vendor=name)
    db.session.add(v)
    db.session.commit()
    return v


def _make_printer(client, auth_headers, **payload):
    resp = client.post('/api/printers', json=payload, headers=auth_headers)
    assert resp.status_code == 201, resp.get_json()
    return resp.get_json()['data']['printer']['printerid']


def test_install_batch_groups_universal_specific_and_manual(
        client, db, auth_headers, printer_assettype):
    hp = _vendor(db, 'HP')
    zebra = _vendor(db, 'Zebra')
    epson = _vendor(db, 'Epson')

    # HP -> universal installer
    hp_id = _make_printer(client, auth_headers, assetnumber='CSF04-WJRP2035-HP',
                          hostname='wjprn04', vendorid=hp.vendorid)
    # Zebra with a .exe installpath -> specific silent install
    zebra_id = _make_printer(client, auth_headers, assetnumber='LABELER-ZEBRA',
                             hostname='wjprn05', vendorid=zebra.vendorid,
                             installpath='./installers/printers/zddriver.exe')
    # Epson with a .zip installpath -> manual (we do not run a .zip /SILENT)
    epson_id = _make_printer(client, auth_headers, assetnumber='RECEIPT-EPSON',
                             hostname='wjprn06', vendorid=epson.vendorid,
                             installpath='./installers/printers/c350navi.zip')

    ids = '%d,%d,%d' % (hp_id, zebra_id, epson_id)
    resp = client.get('/api/printers/install-batch?printerids=' + ids,
                      headers=auth_headers)
    assert resp.status_code == 200
    assert 'application/octet-stream' in resp.headers['Content-Type']
    assert '.bat' in resp.headers['Content-Disposition']

    bat = resp.get_data(as_text=True)
    # Universal group: HP printer name in a /PRINTER list + PrinterInstaller.exe
    assert 'PrinterInstaller.exe' in bat
    assert '/PRINTER="CSF04-WJRP2035-HP"' in bat
    # Specific: the .exe installpath resolved + run /SILENT
    assert 'installers/printers/zddriver.exe' in bat
    assert '/SILENT' in bat
    # Manual: the .zip printer is flagged, NOT executed
    assert 'MANUAL' in bat
    assert 'RECEIPT-EPSON' in bat
    assert 'c350navi.zip' not in bat  # never handed to the runner


def test_install_batch_resolves_vendor_via_model(
        client, db, auth_headers, printer_assettype):
    """A printer with no direct vendorid still groups as universal when its
    MODEL's vendor is HP/Xerox (the import sets the model, not the printer's
    vendorid) - the bug that dumped every prod printer into 'manual (unknown)'."""
    from shopdb.core.models import Vendor, Model

    xerox = Vendor(vendor='Xerox')
    db.session.add(xerox)
    db.session.commit()
    model = Model(modelnumber='VersaLink C7125', vendorid=xerox.vendorid)
    db.session.add(model)
    db.session.commit()

    # No vendorid on the printer - only the model ties it to Xerox.
    pid = _make_printer(client, auth_headers, assetnumber='SpoolsInspection-Xerox',
                        hostname='wjprn07', modelnumberid=model.modelnumberid)

    resp = client.get('/api/printers/install-batch?printerids=%d' % pid,
                      headers=auth_headers)
    assert resp.status_code == 200
    bat = resp.get_data(as_text=True)
    assert 'PrinterInstaller.exe' in bat
    assert '/PRINTER="SpoolsInspection-Xerox"' in bat
    assert 'MANUAL' not in bat


def test_install_batch_requires_ids(client, db, auth_headers, printer_assettype):
    resp = client.get('/api/printers/install-batch', headers=auth_headers)
    assert resp.status_code == 400
