"""Per-image-type state probes: status + config (drivers / OS / packages / models)."""

import os

import config
from services import fs


def image_status(image_type):
    """Return a dict describing the state of an image type."""
    dp = fs.deploy_path(image_type)
    up = fs.unattend_path(image_type)
    has_content = os.path.isdir(dp) and any(os.scandir(dp)) if os.path.isdir(dp) else False
    has_unattend = os.path.isfile(up)
    return {
        "image_type": image_type,
        "friendly_name": config.FRIENDLY_NAMES.get(image_type, image_type),
        "deploy_path": dp,
        "has_content": has_content,
        "has_unattend": has_unattend,
    }


def load_image_config(image_type):
    """Load all JSON configs for an image and check on-disk presence."""
    ctrl = fs.control_path(image_type)
    tools = fs.tools_path(image_type)

    # --- Drivers (merge HardwareDriver.json + hw_drivers.json) ---
    hw_driver_file = os.path.join(ctrl, "HardwareDriver.json")
    hw_drivers_extra = os.path.join(ctrl, "hw_drivers.json")
    drivers_raw = fs.load_json(hw_driver_file)
    extra_raw = fs.load_json(hw_drivers_extra)

    seen_files = set()
    drivers = []
    for d in drivers_raw + extra_raw:
        fname = (d.get("FileName") or d.get("fileName") or "").lower()
        if fname and fname in seen_files:
            continue
        if fname:
            seen_files.add(fname)
        drivers.append(d)

    for d in drivers:
        fname = d.get("FileName") or d.get("fileName") or ""
        dest = d.get("DestinationDir") or d.get("destinationDir") or ""
        resolved = fs.resolve_destination(dest, image_type)
        if resolved and fname:
            d["_on_disk"] = os.path.isfile(os.path.join(resolved, fname))
        else:
            d["_on_disk"] = False

    # --- Operating Systems ---
    os_file = os.path.join(ctrl, "OperatingSystem.json")
    operating_systems = fs.load_json(os_file)
    for entry in operating_systems:
        osv = entry.get("operatingSystemVersion", {})
        wim = osv.get("wim", {})
        dest = wim.get("DestinationDir") or wim.get("destinationDir") or ""
        resolved = fs.resolve_destination(dest, image_type)
        if resolved:
            entry["_on_disk"] = os.path.isfile(os.path.join(resolved, "install.wim"))
        else:
            entry["_on_disk"] = False

    # --- Packages ---
    pkg_file = os.path.join(ctrl, "packages.json")
    packages = fs.load_json(pkg_file)
    for p in packages:
        fname = p.get("fileName") or p.get("FileName") or ""
        dest = p.get("destinationDir") or p.get("DestinationDir") or ""
        resolved = fs.resolve_destination(dest, image_type)
        if resolved and fname:
            p["_on_disk"] = os.path.isfile(os.path.join(resolved, fname))
        else:
            p["_on_disk"] = False

    # --- Hardware Models (user_selections.json) ---
    us_file = os.path.join(tools, "user_selections.json")
    us_raw = fs.load_json(us_file)
    us_data = us_raw[0] if us_raw and isinstance(us_raw, list) else {}
    hardware_models = us_data.get("HardwareModelSelection", [])
    os_selection = str(us_data.get("OperatingSystemSelection", ""))

    family_lookup = {}
    for d in drivers:
        family = d.get("family", "")
        if family:
            family_lookup[family] = d

    for hm in hardware_models:
        family_id = hm.get("Id", "")
        matched = family_lookup.get(family_id)
        hm["_on_disk"] = matched["_on_disk"] if matched else False

    # --- Orphan drivers: zip files on disk not referenced in any JSON ---
    orphan_drivers = []
    oob_dir = os.path.join(fs.deploy_path(image_type), "Out-of-box Drivers")
    try:
        oob_dir = os.path.realpath(oob_dir)
    except OSError:
        pass
    registered_files = set()
    for d in drivers:
        fname = d.get("FileName") or d.get("fileName") or ""
        if fname:
            registered_files.add(fname.lower())
    if os.path.isdir(oob_dir):
        for dirpath, _dirnames, filenames in os.walk(oob_dir):
            for fn in filenames:
                if fn.lower().endswith(".zip") and fn.lower() not in registered_files:
                    rel = os.path.relpath(os.path.join(dirpath, fn), oob_dir)
                    orphan_drivers.append({"fileName": fn, "relPath": rel})

    return {
        "hardware_models": hardware_models,
        "drivers": drivers,
        "operating_systems": operating_systems,
        "packages": packages,
        "orphan_drivers": orphan_drivers,
        "os_selection": os_selection,
    }
