#!/usr/bin/env php
<?php
/**
 * Smoke test for 3x-ui v3 API integration.
 *
 * Usage:
 *   php scripts/smoke-test-xui-v3.php --server-id=1 --inbound-id=3
 *   php scripts/smoke-test-xui-v3.php --base-url=https://panel.example.com --token=SECRET --inbound-id=3
 *
 * Requires xui-env.local.php or environment variables.
 */
if (php_sapi_name() !== 'cli') {
    fwrite(STDERR, "CLI only\n");
    exit(1);
}

$root = dirname(__DIR__);
require_once $root . '/baseInfo.php';
require_once $root . '/services/XuiV3Config.php';
require_once $root . '/services/XuiV3ApiClient.php';
require_once $root . '/services/XuiV3Service.php';

$opts = getopt('', ['server-id:', 'base-url:', 'token:', 'inbound-id:', 'verify-sub::']);
$inboundId = isset($opts['inbound-id']) ? (int) $opts['inbound-id'] : 0;

if (!empty($opts['server-id'])) {
    require_once $root . '/config.php';
    $serverInfo = getServerInfoById((int) $opts['server-id']);
    if (!$serverInfo) {
        fwrite(STDERR, "Server not found\n");
        exit(1);
    }
    $service = new XuiV3Service($serverInfo);
} else {
    XuiV3Config::loadGlobals();
    $config = XuiV3Config::forServer([
        'type' => 'sanaei',
        'panel_url' => $opts['base-url'] ?? '',
        'api_token' => $opts['token'] ?? getenv('XUI_API_TOKEN'),
        'xui_v3_enabled' => true,
    ]);
    $client = new XuiV3ApiClient($config);
    $service = new class($client, $config) {
        private $client;
        private $config;
        public function __construct($c, $cfg) { $this->client = $c; $this->config = $cfg; }
        public function getApiClient() { return $this->client; }
        public function buildSubscriptionUrl($subId) {
            return rtrim($this->config['subscription_base_url'], '/') . $this->config['sub_path'] . rawurlencode($subId);
        }
        public function createClient($email, $inboundId, $totalBytes, $expiryMs, $limitIp = 1, $tgId = 0, $comment = '', $subId = null) {
            $subId = $subId ?: bin2hex(random_bytes(8));
            $payload = [
                'client' => [
                    'email' => $email,
                    'subId' => $subId,
                    'totalGB' => $totalBytes,
                    'expiryTime' => $expiryMs,
                    'tgId' => $tgId,
                    'limitIp' => $limitIp,
                    'enable' => true,
                    'comment' => $comment,
                ],
                'inboundIds' => [(int) $inboundId],
            ];
            $r = $this->client->addClient($payload);
            return (object) ['success' => $r->success, 'msg' => $r->msg, 'obj' => (object) ['subId' => $subId]];
        }
        public function deleteClientByEmail($email) {
            $r = $this->client->deleteClient($email, false);
            return (object) ['success' => $r->success, 'msg' => $r->msg];
        }
    };
}

$client = $service->getApiClient();
$passed = 0;
$failed = 0;

function step($name, $ok, $detail = '') {
    global $passed, $failed;
    if ($ok) {
        echo "[PASS] $name\n";
        $passed++;
    } else {
        echo "[FAIL] $name" . ($detail ? " — $detail" : '') . "\n";
        $failed++;
    }
}

$status = $client->getServerStatus();
step('GET /panel/api/server/status', $status->success, $status->msg);

$options = $client->getInboundOptions();
step('GET /panel/api/inbounds/options', $options->success, $options->msg);

$testEmail = 'wizwiz-smoke-' . time() . '@test.local';
$subId = null;
$subUrl = null;

if ($inboundId > 0) {
    $expiry = (int) (microtime(true) * 1000) + 86400000;
    $create = $service->createClient($testEmail, $inboundId, 1073741824, $expiry, 1, 0, 'smoke-test');
    step('POST /panel/api/clients/add', $create->success, $create->msg);

    $get = $client->getClient($testEmail);
    step('GET /panel/api/clients/get/{email}', $get->success, $get->msg);

    if ($get->success && is_object($get->obj)) {
        $c = $get->obj->client ?? $get->obj;
        $subId = is_object($c) ? ($c->subId ?? null) : null;
    }

    if ($subId) {
        $subUrl = method_exists($service, 'buildSubscriptionUrl')
            ? $service->buildSubscriptionUrl($subId)
            : '';
        step('Build subscription URL', !empty($subUrl), $subUrl);

        if (isset($opts['verify-sub']) && !empty($subUrl)) {
            $ch = curl_init($subUrl);
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_FOLLOWLOCATION => true,
                CURLOPT_TIMEOUT => 15,
                CURLOPT_SSL_VERIFYPEER => false,
            ]);
            $body = curl_exec($ch);
            $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            step('Subscription HTTP 200 + body', $code === 200 && strlen((string) $body) > 0, "http=$code len=" . strlen((string) $body));
        }
    }

    $del = $service->deleteClientByEmail($testEmail);
    step('POST /panel/api/clients/del/{email}', $del->success, $del->msg);
} else {
    echo "[SKIP] client create/delete — pass --inbound-id=N\n";
}

echo "\nSummary: $passed passed, $failed failed\n";
exit($failed > 0 ? 1 : 0);
