#!/usr/bin/env python3
"""End-to-end Python smoke: REST create/power/guest-file + SOAP CreateVM_Task."""

from __future__ import annotations

import os
import sys
import xml.etree.ElementTree as ET

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!")


def rest_session() -> 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 rest_lifecycle(headers: dict[str, str]) -> str:
    created = requests.post(
        f"{BASE}/api/vcenter/vm",
        headers=headers,
        json={
            "name": "py-rest-lab-01",
            "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},
        },
        verify=False,
        timeout=60,
    )
    created.raise_for_status()
    vm = created.json()
    power = requests.post(
        f"{BASE}/api/vcenter/vm/{vm}/power",
        params={"action": "start"},
        headers=headers,
        verify=False,
        timeout=60,
    )
    power.raise_for_status()
    assert "task" in power.json()
    put = requests.put(
        f"{BASE}/api/vcenter/vm/{vm}/guest/filesystem",
        params={"path": "/tmp/python-marker"},
        headers=headers,
        json={"content": "ok"},
        verify=False,
        timeout=60,
    )
    put.raise_for_status()
    requests.post(
        f"{BASE}/api/vcenter/vm/{vm}/power",
        params={"action": "stop"},
        headers=headers,
        verify=False,
        timeout=60,
    ).raise_for_status()
    requests.delete(
        f"{BASE}/api/vcenter/vm/{vm}", headers=headers, verify=False, timeout=60
    ).raise_for_status()
    return vm


def soap_create_vm(session_id: str) -> str:
    envelope = """<?xml version="1.0"?>
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Body>
        <CreateVM_Task xmlns="urn:vim25">
          <_this type="Folder">group-v23</_this>
          <config>
            <name>py-soap-lab-01</name>
            <guestId>otherGuest64</guestId>
            <numCPUs>1</numCPUs>
            <memoryMB>512</memoryMB>
            <files><vmPathName>[datastore1]</vmPathName></files>
          </config>
          <pool type="ResourcePool">resgroup-22</pool>
          <host type="HostSystem">host-11</host>
        </CreateVM_Task>
      </soapenv:Body>
    </soapenv:Envelope>"""
    response = requests.post(
        f"{BASE}/sdk",
        data=envelope,
        headers={
            "Content-Type": "text/xml",
            "vmware-api-session-id": session_id,
            "Cookie": f'vmware_soap_session="{session_id}"',
        },
        verify=False,
        timeout=60,
    )
    response.raise_for_status()
    root = ET.fromstring(response.text)
    task = None
    for node in root.iter():
        if node.tag.endswith("returnval") and (node.text or "").startswith("task-"):
            task = node.text
            break
    assert task, response.text
    return task


def main() -> int:
    headers = rest_session()
    rest_vm = rest_lifecycle(headers)
    soap_task = soap_create_vm(headers["vmware-api-session-id"])
    print(f"REST VM lifecycle ok: {rest_vm}")
    print(f"SOAP CreateVM_Task ok: {soap_task}")
    return 0


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