<?php

declare(strict_types=1);

namespace PpPhp\Core\Migrate;

/**
 * Plants the migration agent inside a bundle and mints its one-time access token.
 *
 * The bundle that gets transported carries the agent script plus `agent-meta.json`
 * holding only the SHA-256 HASH of the token — never the token itself. The raw
 * token is returned to the caller, which keeps it on the source (in the job folder,
 * outside the bundle) so nothing that travels to the destination can be replayed to
 * authenticate against the agent.
 */
final class AgentBuilder
{
    public const AGENT_FILE = 'pp-migrate-agent.php';
    public const META_FILE  = 'agent-meta.json';

    /** Path to the agent source template shipped with the platform. */
    private static function template(): string
    {
        return __DIR__ . '/agent/' . self::AGENT_FILE;
    }

    /**
     * Write the agent + meta into $bundleDir and return the RAW token.
     *
     * @return array{token:string,tokenHash:string,path:string}
     */
    public static function install(string $bundleDir, string $jobId, string $sourceHost = ''): array
    {
        $token     = bin2hex(random_bytes(24));            // 48 hex chars
        $tokenHash = hash('sha256', $token);

        @copy(self::template(), $bundleDir . '/' . self::AGENT_FILE);

        $meta = [
            'jobId'        => $jobId,
            'tokenHash'    => $tokenHash,
            'created'      => gmdate('c'),
            'sourceHost'   => $sourceHost,
            'agentVersion' => '1.0.0',
        ];
        @file_put_contents(
            $bundleDir . '/' . self::META_FILE,
            json_encode($meta, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)
        );

        return ['token' => $token, 'tokenHash' => $tokenHash,
                'path' => $bundleDir . '/' . self::AGENT_FILE];
    }

    /**
     * The remote directory the bundle is uploaded into, relative to the
     * destination base path. Kept deliberately unguessable-ish by job id.
     */
    public static function remoteSubdir(string $jobId): string
    {
        return '_ppmigrate/' . preg_replace('/[^A-Za-z0-9\-]/', '', $jobId);
    }
}
