<?php

namespace App\Provisioning\Steps\Host;

use App\Models\ProvisioningRun;
use App\Provisioning\StepResult;
use App\Services\Ssh\RemoteShell;
use App\Support\ProvisioningSettings;
use Illuminate\Support\Facades\Crypt;

/**
 * First login with the one-time root password, deploy CluPilot's SSH key, pin
 * the host key, verify key login, then scrub the password from the run context.
 */
class EstablishSshTrust extends HostStep
{
    public function __construct(private RemoteShell $shell) {}

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

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

        // Idempotent: already trusted (host key pinned) and password already scrubbed.
        if (filled($host->ssh_host_key) && blank($run->context('root_password'))) {
            return StepResult::advance();
        }

        $publicKey = trim(ProvisioningSettings::sshPublicKey());
        $password = Crypt::decryptString((string) $run->context('root_password'));

        $this->shell->connectWithPassword($host->public_ip, 'root', $password);
        $this->shell->run('mkdir -p /root/.ssh && chmod 700 /root/.ssh');
        $this->shell->run(
            'grep -qxF '.escapeshellarg($publicKey).' /root/.ssh/authorized_keys 2>/dev/null '.
            '|| echo '.escapeshellarg($publicKey).' >> /root/.ssh/authorized_keys'
        );

        $host->update(['ssh_host_key' => $this->shell->hostKeyFingerprint()]);

        // Verify the key works, then remove the password from state.
        $this->keyLogin($this->shell, $host);
        $run->forgetContext('root_password');

        return StepResult::advance();
    }
}
