<?php

declare(strict_types=1);

// Bounded SELECT-only discriminator. EXTRA_DECIMAL is deliberately never set.
$phase = 'preflight';
$mode = (string) getenv('CDX_PLAIN_MODE');
try {
    $root = realpath((string) getenv('POC_APP_ROOT'));
    if (!$root || strpos($root, '/tmp/zhct-') !== 0
        || !in_array($mode, ['default', 'stringify'], true)) {
        throw new RuntimeException('Approved isolated mode required');
    }
    foreach (['HOST', 'PORT', 'SCHEMA', 'USER', 'PASSWORD'] as $part) {
        if ((string) getenv('POC_AI_' . $part) === '') {
            throw new RuntimeException('Approved AI runtime environment required');
        }
    }
    $phase = 'bootstrap';
    require $root . '/vendor/autoload.php';
    $config = [
        'type' => \app\common\database\Dm::class,
        'hostname' => getenv('POC_AI_HOST'),
        'hostport' => (int) getenv('POC_AI_PORT'),
        'database' => getenv('POC_AI_SCHEMA'),
        'username' => getenv('POC_AI_USER'),
        'password' => getenv('POC_AI_PASSWORD'),
        'prefix' => '',
        'debug' => false,
        'params' => [
            PDO::ATTR_CASE => PDO::CASE_LOWER,
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_STRINGIFY_FETCHES => $mode === 'stringify',
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
        ],
    ];
    $manager = new \think\DbManager();
    $manager->setConfig(['default' => 'probe', 'connections' => ['probe' => $config]]);
    $db = $manager->connect('probe');
    $sql = "SELECT 7 AS I,CAST('9007199254740993.01' AS DECIMAL(30,2)) AS D,"
        . "CAST('0.00' AS DECIMAL(5,2)) AS Z FROM DUAL";
    $table = '(' . $sql . ') EXACT_Q';
    foreach (['query', 'find', 'select'] as $phase) {
        fwrite(STDERR, 'PLAIN_BEGIN ' . $mode . ' ' . $phase . PHP_EOL);
        if ($phase === 'query') {
            $rows = $db->query($sql);
        } elseif ($phase === 'find') {
            $rows = $db->table($table)->where('i', 7)->find();
        } else {
            $rows = $db->table($table)->select();
            if (is_object($rows) && method_exists($rows, 'toArray')) {
                $rows = $rows->toArray();
            }
        }
        $first = $phase === 'find' ? $rows : ($rows[0] ?? null);
        $types = [];
        foreach (is_array($first) ? $first : [] as $name => $value) {
            $types[$name] = gettype($value);
        }
        fwrite(STDERR, 'PLAIN_DONE ' . $mode . ' ' . $phase
            . ' top=' . gettype($rows)
            . ' count=' . (is_array($rows) ? count($rows) : -1)
            . ' field_types=' . json_encode($types) . PHP_EOL);
    }
    echo json_encode(['php' => PHP_VERSION, 'status' => 'pass', 'mode' => $mode,
        'extra_decimal_used' => false, 'business_writes' => 0]) . PHP_EOL;
} catch (Throwable $error) {
    echo json_encode(['php' => PHP_VERSION, 'status' => 'fail', 'mode' => $mode,
        'phase' => $phase, 'error_class' => get_class($error),
        'error_code' => $error->getCode()]) . PHP_EOL;
    exit(1);
}
