"""Every declared dashboard card obeys the contract.

Five plugins once declared widgets naming Vue components that were never
written, and nothing rendered - the frontend did not call the endpoint either,
so the mismatch went unnoticed for months. These tests make that class of
mistake impossible to repeat quietly: a declaration is checked against the
contract, and its endpoint must actually exist.
"""

import pytest

RENDERERS = ('exceptions', 'metric', 'list')


def _declared(app):
    pm = app.extensions['plugin_manager']
    cards = []
    for name, plugin in pm.get_all_plugins().items():
        for card in plugin.get_dashboard_widgets() or []:
            cards.append((name, card))
    return cards


def test_there_are_cards_to_check(app):
    with app.app_context():
        assert _declared(app), 'no plugin declares a dashboard card'


def test_no_card_names_a_frontend_component(app):
    """The old contract. It cannot survive a lean build, where a plugin's
    component may never be staged into the bundle."""
    with app.app_context():
        named = [(p, c.get('id') or c.get('name')) for p, c in _declared(app)
                 if 'component' in c]
        assert named == []


def test_every_card_declares_the_fields_core_renders_from(app):
    with app.app_context():
        for pluginname, card in _declared(app):
            assert card.get('id'), pluginname
            assert card.get('title'), card
            assert card.get('endpoint'), card
            assert card.get('render') in RENDERERS, card
            assert card.get('severity') in ('critical', 'warning', 'info'), card


def test_every_card_endpoint_is_a_real_route(app):
    """A declaration pointing at a route nobody wrote is exactly how the old
    widgets rotted."""
    with app.app_context():
        rules = {str(rule) for rule in app.url_map.iter_rules()}
        for pluginname, card in _declared(app):
            endpoint = card['endpoint'].split('?')[0]
            assert endpoint in rules, '{}: {} is not a route'.format(
                pluginname, endpoint)


def test_every_card_links_somewhere(app):
    """A row that names a problem without linking to it is a worse report."""
    with app.app_context():
        for pluginname, card in _declared(app):
            if card['render'] == 'metric':
                continue
            assert (card.get('map') or {}).get('link'), card


def test_a_viewall_target_is_one_of_the_known_pages(app):
    """A card's overflow line links here. Pointing it at a route nobody wrote is
    the same rot the endpoint check exists to stop - it just fails in the
    browser instead of the API."""
    known = {
        '/pcs', '/machines', '/printers', '/network', '/notifications',
        '/geenforce', '/reports/toner', '/reports/warranty',
        '/reports/pc-relationships', '/reports/calibration', '/reports',
    }
    with app.app_context():
        for pluginname, card in _declared(app):
            target = card.get('viewall')
            if target is None:
                continue
            assert target in known, '{}: {} is not a known page'.format(
                pluginname, target)
