<?php
declare(strict_types=1);

// Read-only nonproduction AI5238 administrator capability probe. Secret is
// supplied on STDIN and never persisted or printed.
$password = trim((string)stream_get_contents(STDIN));
if (strlen($password) < 16) {
    fwrite(STDERR, "Administrator input unavailable\n");
    exit(78);
}
try {
    $db = new PDO('dm:host=127.0.0.1;port=5238;schema=SYSDBA', 'SYSDBA',
        $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_TIMEOUT => 5]);
    $password = '';
    $user = strtoupper((string)$db->query('SELECT USER FROM DUAL')->fetchColumn());
    $schema = strtoupper((string)$db->query(
        "SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")
        ->fetchColumn());
    if ($user !== 'SYSDBA' || $schema !== 'SYSDBA') {
        throw new RuntimeException('Administrator identity mismatch');
    }
    $rights = $db->query("SELECT PRIVILEGE FROM USER_SYS_PRIVS WHERE PRIVILEGE IN"
        . " ('CREATE ANY TABLE','ALTER ANY TABLE','DROP ANY TABLE')"
        . ' ORDER BY PRIVILEGE')->fetchAll(PDO::FETCH_COLUMN);
    $roles = $db->query('SELECT GRANTED_ROLE FROM USER_ROLE_PRIVS ORDER BY GRANTED_ROLE')
        ->fetchAll(PDO::FETCH_COLUMN);
    $rows = $db->query("SELECT PARA_NAME,PARA_VALUE FROM V\$DM_INI WHERE PARA_NAME IN"
        . " ('ALTER_TABLE_OPT','DDL_AUTO_COMMIT','ENABLE_DDL_ANY_PRIV')"
        . ' ORDER BY PARA_NAME')->fetchAll(PDO::FETCH_ASSOC);
    $settings = [];
    foreach ($rows as $row) {
        $settings[(string)$row['para_name']] = (string)$row['para_value'];
    }
    echo json_encode(['target' => 'nonproduction-ai-5238', 'user' => $user,
        'schema' => $schema, 'direct_rights' => $rights,
        'roles' => $roles, 'settings' => $settings,
        'ddl_executed' => false, 'dml_executed' => false],
        JSON_UNESCAPED_SLASHES) . PHP_EOL;
} catch (Throwable $error) {
    $password = '';
    echo json_encode(['status' => 'read_only_probe_failed',
        'class' => get_class($error), 'code' => (string)$error->getCode(),
        'message_sha256' => hash('sha256', $error->getMessage()),
        'ddl_executed' => false, 'dml_executed' => false]) . PHP_EOL;
    exit(1);
}
