#!/usr/bin/env python3
"""Driver coverage for membrowse's CI boards and the HIL board pool.

Every dcd_*/hcd_* driver under src/portable (plus ehci/ohci, minus template/)
is checked against two rosters: `.github/ci-pinned-boards.json` and the HIL
rig rosters (test/hil/tinyusb.json, test/hil/hfp.json - which board family,
if any, on the physical rig builds it).

A pinned board covers the drivers its default configure compiles, per its
hw/bsp/family.json row: `cmake.portable` filtered by `cmake.roles` - dcd_*
counts with a device or dual role, hcd_*/ehci/ohci with host or dual. This
trusts family.json, so coverage is only as fresh as the catalog: a
skip.txt/only.txt/example CMakeLists.txt edit shows up at its next refresh.
`uncovered` waives drivers with a reason; a waiver may overlap a driver the
pinned boards compile (e.g. an empty build without its CFG_ option).

Fatal, one line per error to stderr, exit 1: malformed json, a non-object or
board-less or duplicate entry, an unknown board, a pinned board with no
family.json row or a null cmake row, a family no CI toolchain builds
(ci_set_matrix.family_list), a waiver naming no driver source file or with a
blank reason, and a driver neither covered nor waived. Exit 0 otherwise, with
INFO lines on stdout: each waiver with the pinned boards it suppresses, and
drivers with no rig board.

The HIL family mapping reuses tools/ci_select.py's rule-3/4 machinery
(port_families()/port_option_gates()/board_roles(), the same data and role
filter that pick which rig boards a src/portable/ diff selects) rather than
a second heuristic.
"""
import functools
import json
import os
import sys

REPO = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
FAMILY_JSON = os.path.join(REPO, 'hw', 'bsp', 'family.json')
PORTABLE = os.path.join(REPO, 'src', 'portable')
sys.path.insert(0, os.path.join(REPO, 'tools'))
import ci_select  # noqa: E402
sys.path.insert(0, os.path.join(REPO, '.github', 'scripts'))
import ci_set_matrix  # noqa: E402


def _is_host_driver(d):
    return d.startswith('hcd_') or d in ('ehci', 'ohci')


def row_drivers(row):
    """Driver stems a family.json cmake row compiles for a role that uses them."""
    roles = set(row['roles'])
    out = set()
    for src in row['portable']:
        stem = os.path.splitext(os.path.basename(src))[0]
        if _is_host_driver(stem):
            wanted = {'host', 'dual'}
        elif stem.startswith('dcd_'):
            wanted = {'device', 'dual'}
        else:
            continue
        if roles & wanted:
            out.add(stem)
    return out


@functools.lru_cache(maxsize=None)
def list_driver_paths(portable_dir):
    """{stem: source path} for every dcd_*/hcd_* driver plus ehci/ohci, template
    excluded. A stem collision (two files with the same driver name) silently
    keeps whichever os.walk() visits last - the real tree has none today."""
    paths = {}
    for root, _dirs, files in os.walk(portable_dir):
        if os.path.basename(root) == 'template':
            continue
        for f in files:
            stem, ext = os.path.splitext(f)
            if ext != '.c':
                continue
            if stem.startswith(('dcd_', 'hcd_')) or stem in ('ehci', 'ohci'):
                paths[stem] = os.path.join(root, f)
    return paths


def _port_scope(driver_path, gates_by_port, repo_root):
    """(port, families building it, build options gating it) for one driver source."""
    port = _driver_port(driver_path, repo_root)
    if not port:
        return None, set(), set()
    return port, ci_select.port_families(port, repo_root), gates_by_port.get(port, set())


def _load_object(path):
    """(json object, errors): an unreadable, malformed or non-object file is one
    fatal line like every other check, not a traceback."""
    try:
        with open(path) as f:
            data = json.load(f)
    except (OSError, json.JSONDecodeError) as e:
        return None, [f'{path}: {e}']
    if not isinstance(data, dict):
        return None, [f'{path}: top level must be an object']
    return data, []


def _entry_coverage(entry, where, catalog, ci_families):
    """(board or None, driver stems or None, errors) for one roster entry.
    Drivers None means the entry contributes no coverage; a board with an error
    against it can still contribute (an unbuilt family is not an early exit)."""
    if not isinstance(entry, dict):
        return None, None, [f'{where}: must be an object, not {type(entry).__name__}']
    board = entry.get('board')
    # the type check too: a truthy non-string board reaches board_family() as a traceback
    if not (isinstance(board, str) and board):
        return None, None, [f'{where}: missing "board"' if not board else
                            f'{where}: "board" must be a string, not {type(board).__name__}']
    where = f'{where} ({board})'
    family = ci_select.board_family(board, REPO)
    if family is None:
        return board, None, [f'{where}: unknown board (no hw/bsp/*/boards/{board})']
    errors = []
    if family not in ci_families:
        errors.append(
            f'{where}: family "{family}" is pinned but built by no CI toolchain '
            f'(not in ci_set_matrix.family_list), so it covers nothing')
    rows = catalog.get(family)
    if not isinstance(rows, dict) or board not in rows:
        return board, None, errors + [f'{where}: no row in hw/bsp/family.json']
    row = rows[board]
    if not (isinstance(row, dict) and isinstance(row.get('cmake'), dict)):
        return board, None, errors + [
            f'{where}: hw/bsp/family.json row has no cmake configure']
    cmake = row['cmake']
    # row_drivers indexes both straight away: a catalog hand-edited between
    # family.json's own hook and this one must fail as a line, not a traceback
    if not all(isinstance(cmake.get(k), list) and all(isinstance(x, str) for x in cmake[k])
               for k in ('roles', 'portable')):
        return board, None, errors + [
            f'{where}: hw/bsp/family.json cmake row needs string lists '
            f'"roles" and "portable"']
    return board, row_drivers(cmake), errors


def _waiver_errors(uncovered, drivers):
    """One line per waiver naming no driver source file or carrying a blank reason."""
    errors = []
    for d, reason in uncovered.items():
        if d not in drivers:
            errors.append(f'uncovered: "{d}" matches no driver source file')
        if not (isinstance(reason, str) and reason.strip()):
            errors.append(f'uncovered "{d}": reason must be a non-empty string')
    return errors


def pinned_coverage(path, catalog_path=FAMILY_JSON):
    """(errors, {board: driver stems} before waivers, uncovered)."""
    data, load_errors = _load_object(path)
    if load_errors:
        return load_errors, {}, {}
    boards = data.get('boards')
    uncovered = data.get('uncovered', {})
    if not isinstance(boards, list) or not boards:
        return [f'{path}: "boards" must be a non-empty list'], {}, {}
    if not isinstance(uncovered, dict):
        return [f'{path}: "uncovered" must be an object of driver: reason'], {}, {}
    catalog, load_errors = _load_object(catalog_path)
    if load_errors:
        return load_errors, {}, {}

    errors = []
    drivers = set(list_driver_paths(PORTABLE))
    # ci_set_matrix.family_list is the ground truth for which families CI builds at
    # all - espressif included, with no toolchain, since hil-build-esp builds it by
    # board name rather than as a matrix leg.
    ci_families = set(ci_set_matrix.family_list)
    coverage = {}
    for i, entry in enumerate(boards):
        board, board_drivers, entry_errors = _entry_coverage(
            entry, f'boards[{i}]', catalog, ci_families)
        if board is not None and board in coverage:
            errors.append(f'boards[{i}] ({board}): duplicate entry')
            continue
        errors += entry_errors
        if board_drivers is not None:
            coverage[board] = board_drivers

    errors += _waiver_errors(uncovered, drivers)

    covered = set().union(*coverage.values())
    for d in sorted(drivers - covered - set(uncovered)):
        errors.append(f'membrowse: {d} has no CI board and no uncovered entry')
    return errors, coverage, uncovered


def check(path, catalog_path=FAMILY_JSON):
    """Fatal roster validity and undocumented coverage errors, one line each."""
    return pinned_coverage(path, catalog_path)[0]


def membrowse_gaps(coverage, uncovered):
    """('INFO', message) per waiver, naming the pinned boards whose compiled
    driver it suppresses. Only meaningful once check() passed."""
    out = []
    for d, reason in sorted(uncovered.items()):
        boards = sorted(b for b, drivers in coverage.items() if d in drivers)
        which = f'suppresses: {", ".join(boards)}' if boards else 'no candidates'
        out.append(('INFO', f'membrowse: {d} uncovered - {reason} ({which})'))
    return out


def _driver_port(driver_path, repo_root):
    """Port dir per ci_select's rule-3/4 extraction, e.g. 'synopsys/dwc2' from
    'src/portable/synopsys/dwc2/dcd_dwc2.c', or None if it doesn't match (it
    always should - DriverScan pins the tree shape ci_select._PORT_PATH_RE
    expects)."""
    rel = os.path.relpath(driver_path, repo_root).replace(os.sep, '/')
    m = ci_select._PORT_PATH_RE.match(rel)
    return m.group(1) if m else None


def _hil_roster_boards(repo_root):
    boards = {}
    for name in ('tinyusb.json', 'hfp.json'):
        with open(os.path.join(repo_root, 'test', 'hil', name)) as f:
            for board in json.load(f).get('boards', []):
                boards.setdefault(board['name'], board)
    return list(boards.values())


def hil_gaps(repo_root=REPO):
    """('INFO', message) for every driver with no board on the HIL rig.
    A driver is covered when a roster board (a) has the matching role for the
    driver - device for dcd_*, host for hcd_*/ehci/ohci, checked against
    ci_select.board_roles(), exactly the `board_roles(b) & roles` filter
    rule 3/4 applies - and (b) either its family is in the driver's port's
    family set (ci_select.port_families - the same family.cmake references
    rule 3/4 reads for a src/portable/ diff) or it turns on a build option
    that gates the port regardless of family (ci_select.port_option_gates/
    board_options - e.g. analog/max3421's MAX3421_HOST)."""
    roster_boards = _hil_roster_boards(repo_root)
    gates_by_port = ci_select.port_option_gates(repo_root)
    driver_paths = list_driver_paths(os.path.join(repo_root, 'src', 'portable'))
    out = []
    for d in sorted(driver_paths):
        _port, fams, gates = _port_scope(driver_paths[d], gates_by_port, repo_root)
        # not ci_select._port_roles: bare ehci.c/ohci.c would read as "both" roles there
        role = 'host' if _is_host_driver(d) else 'device'
        covered = any(
            (ci_select.board_family(b['name'], repo_root) in fams or
             (gates and ci_select.board_options(b, repo_root) & gates)) and
            role in ci_select.board_roles(b)
            for b in roster_boards)
        if not covered:
            out.append(('INFO', f'hil: {d} has no board on the rig'))
    return out


def main():
    path = sys.argv[1] if len(sys.argv) > 1 else os.path.join(
        REPO, '.github', 'ci-pinned-boards.json')
    catalog_path = sys.argv[2] if len(sys.argv) > 2 else FAMILY_JSON
    errors, coverage, uncovered = pinned_coverage(path, catalog_path)
    for e in errors:
        print(e, file=sys.stderr)
    if errors:
        return 1
    gaps = membrowse_gaps(coverage, uncovered) + hil_gaps()
    for level, msg in gaps:
        print(f'{level}: {msg}')
    return 0


if __name__ == '__main__':
    sys.exit(main())
