<?php

namespace App\Provisioning\Steps\Host;

use App\Models\ProvisioningRun;
use App\Provisioning\StepResult;
use App\Services\Proxmox\ProxmoxClient;

/**
 * Reads node capacity from Proxmox and stores it on the host so placement can
 * use it. Idempotent (overwrites).
 */
class RegisterCapacity extends HostStep
{
    public function __construct(private ProxmoxClient $pve) {}

    public function key(): string
    {
        return 'register_capacity';
    }

    public function execute(ProvisioningRun $run): StepResult
    {
        $host = $this->host($run);
        $client = $this->pve->forHost($host);

        $nodes = $client->listNodes();
        $node = $nodes[0]['node'] ?? 'pve';

        $status = $client->nodeStatus($node);
        $storage = $client->nodeStorage($node);

        $cores = (int) ($status['cpuinfo']['cpus'] ?? 0);
        $ramMb = (int) round((int) ($status['memory']['total'] ?? 0) / 1048576);

        // Proxmox lists overlapping pools (e.g. local + local-lvm on one disk).
        // Take the largest VM-capable datastore instead of summing, so shared
        // backing storage is never double-counted and placement can't overcommit.
        $allocatable = array_filter($storage, function ($s) {
            $content = (string) ($s['content'] ?? '');

            return str_contains($content, 'images') || str_contains($content, 'rootdir');
        });
        $pool = $allocatable ?: $storage;
        $totalBytes = $pool === [] ? 0 : max(array_map(fn ($s) => (int) ($s['total'] ?? 0), $pool));
        $totalGb = (int) round($totalBytes / 1073741824);

        $host->update([
            'cpu_cores' => $cores,
            'cpu_weight' => $cores,
            'total_ram_mb' => $ramMb,
            'total_gb' => $totalGb,
            'pve_version' => $status['pveversion'] ?? null,
            'node' => $node,
            'last_seen_at' => now(),
        ]);

        return StepResult::advance();
    }
}
