#!/usr/bin/env python3
"""Raw `requests` cookbook against the vSphere REST gateway (no vsphere-automation-sdk)."""

from __future__ import annotations

import os
import sys
import time
from typing import Any

import requests
import urllib3

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

BASE = os.environ.get("VSPHERE_BASE", "https://localhost").rstrip("/")
USER = os.environ.get("VSPHERE_USER", "administrator@vsphere.local")
PASSWORD = os.environ.get("VSPHERE_PASSWORD", "VMware1!")
VM_NAME = os.environ.get("VSPHERE_VM_NAME", "req-lab-01")


def api(
    method: str,
    path: str,
    *,
    headers: dict[str, str] | None = None,
    json_body: dict[str, Any] | None = None,
) -> Any:
    response = requests.request(
        method,
        f"{BASE}{path}",
        headers=headers,
        json=json_body,
        verify=False,  # local self-signed development certificate only
        timeout=60,
    )
    response.raise_for_status()
    if response.status_code == 204 or not response.content:
        return None
    return response.json()


def wait_task(headers: dict[str, str], task: str, timeout: float = 120.0) -> None:
    deadline = time.time() + timeout
    while time.time() < deadline:
        status = api("GET", f"/api/cis/tasks/{task}", headers=headers)
        if status.get("status") in {"SUCCEEDED", "FAILED"}:
            return
        time.sleep(0.3)
    raise TimeoutError(task)


def session_headers() -> dict[str, str]:
    response = requests.post(
        f"{BASE}/api/session",
        auth=(USER, PASSWORD),
        verify=False,
        timeout=60,
    )
    response.raise_for_status()
    return {"vmware-api-session-id": response.json()}


def main() -> int:
    headers = session_headers()
    print("session:", headers["vmware-api-session-id"])

    vms = api("GET", "/api/vcenter/vm", headers=headers)
    print("vms before:", len(vms))

    moid = api(
        "POST",
        "/api/vcenter/vm",
        headers=headers,
        json_body={
            "name": VM_NAME,
            "guest_OS": "OTHER_GUEST_64",
            "placement": {
                "folder": "group-v23",
                "host": "host-11",
                "datastore": "datastore-31",
                "resource_pool": "resgroup-22",
            },
            "cpu": {"count": 1},
            "memory": {"size_MiB": 512},
        },
    )
    print("created:", moid)

    power = api("POST", f"/api/vcenter/vm/{moid}/power?action=start", headers=headers)
    wait_task(headers, power["task"])

    detail = api("GET", f"/api/vcenter/vm/{moid}", headers=headers)
    print("power_state:", detail["power_state"])

    power = api("POST", f"/api/vcenter/vm/{moid}/power?action=stop", headers=headers)
    wait_task(headers, power["task"])

    api("DELETE", f"/api/vcenter/vm/{moid}", headers=headers)
    api("DELETE", "/api/session", headers=headers)
    print("ok")
    return 0


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