<?php
final class PveApi {
  private string $host;
  private string $node;
  private string $tokenId;
  private string $tokenSecret;
  private int $timeout;
  private bool $verifyTls;

  public function __construct(array $cfg) {
    $this->host = $cfg['host'];
    $this->node = $cfg['node'];
    $this->tokenId = $cfg['token_id'];
    $this->tokenSecret = $cfg['token_secret'];
    $this->timeout = (int)($cfg['timeout'] ?? 15);
    $this->verifyTls = (bool)($cfg['verify_tls'] ?? true);
  }

  public function node(): string { return $this->node; }

  /** VMID 100-199 => lxc, 200-299 => qemu */
  public function typeForVmid(int $vmid): string {
    if ($vmid >= 100 && $vmid <= 199) return 'lxc';
    if ($vmid >= 200 && $vmid <= 299) return 'qemu';
    throw new InvalidArgumentException("VMID {$vmid} liegt nicht im ANJUMA Bereich (100-299).");
  }

  public function statusCurrent(int $vmid): array {
    $type = $this->typeForVmid($vmid);
    return $this->request('GET', "/nodes/{$this->node}/{$type}/{$vmid}/status/current")['data'] ?? [];
  }

  /** action: start|stop|reboot|reset (reset nur qemu sinnvoll) */
  public function powerAction(int $vmid, string $action): string {
    $type = $this->typeForVmid($vmid);

    $allowed = ['start','stop','reboot','reset'];
    if (!in_array($action, $allowed, true)) {
      throw new InvalidArgumentException("Ungültige action: {$action}");
    }
    if ($type === 'lxc' && $action === 'reset') {
      throw new InvalidArgumentException("reset gibt's praktisch nur für qemu/VMs.");
    }

    $res = $this->request('POST', "/nodes/{$this->node}/{$type}/{$vmid}/status/{$action}");
    // Proxmox liefert meist UPID als string in data
    return (string)($res['data'] ?? '');
  }

  private function request(string $method, string $path, array $data = null): array {
    $url = "https://{$this->host}:8006/api2/json{$path}";

    $ch = curl_init($url);
    $headers = [
      "Authorization: PVEAPIToken={$this->tokenId}={$this->tokenSecret}",
    ];

    curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_CUSTOMREQUEST  => strtoupper($method),
      CURLOPT_HTTPHEADER     => $headers,
      CURLOPT_TIMEOUT        => $this->timeout,
      CURLOPT_SSL_VERIFYPEER => $this->verifyTls,
      CURLOPT_SSL_VERIFYHOST => $this->verifyTls ? 2 : 0,
    ]);

    if ($data !== null) {
      $headers[] = "Content-Type: application/x-www-form-urlencoded";
      curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    }

    $raw = curl_exec($ch);
    if ($raw === false) {
      throw new RuntimeException("cURL error: " . curl_error($ch));
    }
    $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    $json = json_decode($raw, true);
    if ($code < 200 || $code >= 300) {
      $msg = is_array($json) ? json_encode($json) : $raw;
      throw new RuntimeException("PVE HTTP {$code}: {$msg}");
    }
    return is_array($json) ? $json : [];
  }

  public function listLxc(): array {
    return $this->request('GET', "/nodes/{$this->node}/lxc")['data'] ?? [];
  }

  public function listQemu(): array {
    return $this->request('GET', "/nodes/{$this->node}/qemu")['data'] ?? [];
  }

}
