<?php
declare(strict_types=1);

if (PHP_SAPI !== 'cli') {
    http_response_code(404);
    exit;
}

require_once __DIR__ . '/../app/bootstrap.php';

$options = getopt('', ['bot-id:', 'yes']);
if (!isset($options['yes'])) {
    fwrite(STDOUT, "Usage:\n  php tools/isolate_existing_bots.php --yes [--bot-id=123]\n\n");
    fwrite(STDOUT, "This rebuilds legacy children with fresh private table namespaces.\n");
    fwrite(STDOUT, "Mixed historical child data is not copied because the old shared rows have no reliable bot_id.\n");
    exit(2);
}

$requestedBotId = isset($options['bot-id']) ? (int)$options['bot-id'] : 0;
$sql = "SELECT id FROM bots WHERE (COALESCE(isolation_mode,'legacy_shared') <> 'table_namespace' OR COALESCE(child_db_provider,'') <> 'table_namespace')";
$params = [];
if ($requestedBotId > 0) {
    $sql .= ' AND id=?';
    $params[] = $requestedBotId;
}
$sql .= ' ORDER BY id ASC';
$stmt = $repo->db()->prepare($sql);
$stmt->execute($params);
$ids = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN));
if (!$ids) {
    fwrite(STDOUT, "OK: no legacy/shared child bots found.\n");
    exit(0);
}

// table.php loads the large legacy function set. Rebuilding more than one bot
// in one PHP process would redeclare those functions, so the batch controller
// intentionally launches one clean PHP process per bot.
if ($requestedBotId <= 0 && count($ids) > 1) {
    if (!function_exists('proc_open')) {
        fwrite(STDERR, "FAILED: proc_open is disabled. Run each bot separately:\n");
        foreach ($ids as $id) {
            fwrite(STDERR, "  php tools/isolate_existing_bots.php --yes --bot-id={$id}\n");
        }
        exit(2);
    }

    $failures = 0;
    foreach ($ids as $id) {
        $command = [PHP_BINARY, __FILE__, '--yes', '--bot-id=' . $id];
        $descriptors = [
            0 => ['file', PHP_OS_FAMILY === 'Windows' ? 'NUL' : '/dev/null', 'r'],
            1 => ['pipe', 'w'],
            2 => ['pipe', 'w'],
        ];
        $process = proc_open($command, $descriptors, $pipes, dirname(__DIR__), null, ['bypass_shell' => true]);
        if (!is_resource($process)) {
            $failures++;
            fwrite(STDERR, "FAILED bot {$id}: could not start isolated migration process.\n");
            continue;
        }
        $stdout = stream_get_contents($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[1]);
        fclose($pipes[2]);
        $exitCode = proc_close($process);
        if ($stdout !== false && $stdout !== '') fwrite(STDOUT, $stdout);
        if ($stderr !== false && $stderr !== '') fwrite(STDERR, $stderr);
        if ($exitCode !== 0) $failures++;
    }
    exit($failures === 0 ? 0 : 1);
}

$botId = $ids[0];
try {
    $service = new BotService($repo, $security, $config);
    $service->rebuildLegacyChildIsolation(0, $botId);
    fwrite(STDOUT, "OK: bot {$botId} rebuilt with a fresh isolated namespace.\n");
    exit(0);
} catch (Throwable $e) {
    fwrite(STDERR, "FAILED bot {$botId}: {$e->getMessage()}\n");
    exit(1);
}
