import asyncio
import json
from app.services.eset_service import eset_service

TARGET = "ati-w11-yoga.norva24.lcl".lower()


def parse_devices(payload):
    if isinstance(payload, list):
        return payload
    if not isinstance(payload, dict):
        return []
    return payload.get("devices") or payload.get("items") or payload.get("results") or payload.get("data") or []


def get_next(payload):
    if not isinstance(payload, dict):
        return None
    return payload.get("nextPageToken") or payload.get("next_page_token") or payload.get("nextPage")


def pick(dev, *keys):
    for key in keys:
        val = dev.get(key)
        if isinstance(val, str) and val.strip():
            return val.strip()
    return ""


def extract_first_str(payload, keys):
    if payload is None:
        return None

    key_set = {k.lower() for k in keys}
    stack = [payload]
    while stack:
        cur = stack.pop()
        if isinstance(cur, dict):
            for k, v in cur.items():
                if k.lower() in key_set and isinstance(v, str) and v.strip():
                    return v.strip()
                if isinstance(v, (dict, list)):
                    stack.append(v)
        elif isinstance(cur, list):
            for item in cur:
                if isinstance(item, (dict, list)):
                    stack.append(item)
    return None


async def main():
    page_token = None
    page_size = 200
    max_pages = 50
    found = None

    for _ in range(max_pages):
        payload = await eset_service.list_devices(page_size=page_size, page_token=page_token)
        if not payload:
            print("ERROR: No payload from ESET list_devices")
            return

        devices = parse_devices(payload)
        for device in devices:
            name = pick(device, "displayName", "deviceName", "name").lower()
            fqdn = pick(device, "fqdn", "dnsName", "hostName", "hostname").lower()
            if TARGET in {name, fqdn} or TARGET in name or TARGET in fqdn:
                found = device
                break

        if found:
            break

        page_token = get_next(payload)
        if not page_token or not devices:
            break

    if not found:
        print("NOT_FOUND")
        return

    uuid = pick(found, "deviceUuid", "uuid", "id")
    details = await eset_service.get_device_details(uuid)
    if not details:
        print("FOUND_BUT_NO_DETAILS")
        print("uuid=", uuid)
        return

    software = eset_service.extract_installed_software(details)
    summary = {
        "device_uuid": uuid,
        "device_name": extract_first_str(details, ["displayName", "deviceName", "name"]),
        "user_identifier": extract_first_str(details, [
            "userPrincipalName", "upn", "email", "mail", "loginName", "login", "userName", "lastLoggedInUser", "owner", "ownerUuid"
        ]),
        "serial": extract_first_str(details, ["serialNumber", "serial", "serial_number"]),
        "group": extract_first_str(details, ["parentGroup", "groupPath", "group", "path"]),
        "installed_software_count": len(software),
        "installed_software_first_20": software[:20],
    }

    out_path = "/tmp/eset_ati_w11_yoga.json"
    with open(out_path, "w", encoding="utf-8") as f:
        json.dump({"summary": summary, "raw": details}, f, ensure_ascii=False, indent=2)

    print("FOUND")
    print(json.dumps(summary, ensure_ascii=False, indent=2))
    print("SAVED=", out_path)


if __name__ == "__main__":
    asyncio.run(main())
