"""Which driver a printer installs with.

One row per model was unworkable: HP and Xerox universal drivers cover 41 of the
reference site's 44 printers, so binding a driver to a single model meant 21
near-duplicate rows pointing at one package - a table nobody keeps true, and the
reason 42 of 44 printers could not resolve a driver at all.

The order is most-specific-first, and each step exists for a printer that really
is on this floor: a plotter and a card printer need their own driver, everything
else takes its make's universal one.
"""

import pytest

from shopdb.core.models import Vendor, Model
from plugins.printers.models import Printer, PrinterDriver
from plugins.printers.api.asset_routes import _printer_driver


def _universal():
    return (PrinterDriver.query
            .filter(PrinterDriver.modelnumberid.is_(None),
                    PrinterDriver.isactive == True)
            .order_by(PrinterDriver.name).all())


@pytest.fixture
def fleet(db):
    hp = Vendor(vendor='HP')
    xerox = Vendor(vendor='Xerox')
    db.session.add_all([hp, xerox])
    db.session.flush()

    laserjet = Model(modelnumber='LaserJet M602', vendorid=hp.vendorid)
    designjet = Model(modelnumber='DesignJet T1700', vendorid=hp.vendorid)
    db.session.add_all([laserjet, designjet])
    db.session.flush()

    upd = PrinterDriver(name='HP Universal Print Driver', drivername='HP Universal Printing PS',
                        location=r'\\server\share\hp_upd', vendorid=hp.vendorid, isactive=True)
    plotter = PrinterDriver(name='HP DesignJet T1700', drivername='HP DesignJet T1700dr V4',
                            location=r'\\server\share\designjet', vendorid=hp.vendorid,
                            modelnumberid=designjet.modelnumberid, isactive=True)
    gpd = PrinterDriver(name='Xerox Global Print Driver PCL6',
                        drivername='Xerox Global Print Driver PCL6',
                        location=r'\\server\share\xerox', vendorid=xerox.vendorid, isactive=True)
    db.session.add_all([upd, plotter, gpd])
    db.session.commit()
    return {'hp': hp, 'xerox': xerox, 'laserjet': laserjet, 'designjet': designjet,
            'upd': upd, 'plotter': plotter, 'gpd': gpd}


def test_a_printer_takes_its_makes_universal_driver(fleet):
    """The case that covers most of a floor: no per-model row exists, and none
    should have to."""
    printer = Printer(vendorid=fleet['hp'].vendorid, modelnumberid=fleet['laserjet'].modelnumberid)
    assert _printer_driver(printer, _universal()).name == 'HP Universal Print Driver'


def test_a_model_specific_driver_beats_the_universal_one(fleet):
    """A plotter is not a LaserJet. If the universal driver won here, the
    DesignJet would be installed with a driver that cannot drive it."""
    printer = Printer(vendorid=fleet['hp'].vendorid, modelnumberid=fleet['designjet'].modelnumberid)
    assert _printer_driver(printer, _universal()).name == 'HP DesignJet T1700'


def test_vendors_do_not_bleed_into_each_other(fleet):
    """A Xerox must never resolve to the HP driver, whatever the ordering."""
    printer = Printer(vendorid=fleet['xerox'].vendorid, modelnumberid=None)
    assert _printer_driver(printer, _universal()).name == 'Xerox Global Print Driver PCL6'


def test_a_printer_with_no_vendor_resolves_to_nothing(fleet):
    """Better nothing than a guess: installing the wrong driver is worse than
    reporting that a printer has none."""
    printer = Printer(vendorid=None, modelnumberid=None)
    assert _printer_driver(printer, _universal()) is None


def test_a_make_with_no_driver_row_resolves_to_nothing(db, fleet):
    """A vendor nobody has added a driver for is unresolved, not misresolved."""
    zebra = Vendor(vendor='Zebra')
    db.session.add(zebra)
    db.session.commit()
    printer = Printer(vendorid=zebra.vendorid, modelnumberid=None)
    assert _printer_driver(printer, _universal()) is None


def test_the_pre_vendorid_naming_convention_still_resolves(db, fleet):
    """A site that populated printerdrivers before the column existed matched on
    the vendor word in the driver's NAME. That must keep working, or an upgrade
    silently takes every driver away."""
    epson = Vendor(vendor='Epson')
    db.session.add(epson)
    db.session.flush()
    db.session.add(PrinterDriver(name='Epson ColorWorks universal', drivername='EPSON TM-C3500',
                                 location=r'\\server\share\epson', isactive=True))
    db.session.commit()
    # vendor attached, not just vendorid: the legacy path reads the vendor's
    # NAME, which only exists through the relationship.
    printer = Printer(vendorid=epson.vendorid, modelnumberid=None)
    printer.vendor = epson
    assert _printer_driver(printer, _universal()).name == 'Epson ColorWorks universal'


def test_a_row_that_names_a_vendor_is_not_matched_by_its_text(db, fleet):
    """A driver whose vendorid is set and does NOT match must not then be picked
    up by the name convention: a mis-set vendor would resolve to the wrong
    package, which is worse than resolving to none."""
    brother = Vendor(vendor='Brother')
    db.session.add(brother)
    db.session.flush()
    # Named for Brother, but bound to HP by id - the id is the truth.
    db.session.add(PrinterDriver(name='Brother universal', drivername='Brother Universal',
                                 location=r'\\server\share\brother',
                                 vendorid=fleet['hp'].vendorid, isactive=True))
    db.session.commit()
    printer = Printer(vendorid=brother.vendorid, modelnumberid=None)
    printer.vendor = brother
    assert _printer_driver(printer, _universal()) is None
