<?php

declare(strict_types=1);

// Only the approved non-production DM Store HTTP runtime. No real names or credentials in output.
$root = (string)getenv('POC_APP_ROOT');
$base = rtrim((string)getenv('POC_BASE_URL'), '/');
$runtimePid = (string)getenv('POC_RUNTIME_PID');
if ((string)getenv('POC_DIALECT') !== 'dm'
    || strpos($root, '/tmp/zhct-') !== 0
    || !is_file($root . '/application/base/Security.php')
    || !is_file($root . '/application/p/controller/Station.php')
    || !preg_match('~^http://127\.0\.0\.1:[0-9]+$~', $base)
    || !ctype_digit($runtimePid)) {
    throw new RuntimeException('Approved isolated DM Store runtime missing');
}
$boundaryRaw = @file_get_contents($base . '/__poc_boundary', false,
    stream_context_create(['http' => ['timeout' => 5]]));
$boundary = is_string($boundaryRaw) ? json_decode($boundaryRaw, true) : null;
if (!is_array($boundary) || empty($boundary['external_stubs']) || empty($boundary['redis_isolated'])) {
    throw new RuntimeException('Isolated HTTP side-effect boundary absent');
}

$env = [];
foreach (['POC_HOST', 'POC_PORT', 'POC_SCHEMA', 'POC_USER', 'POC_PASSWORD'] as $key) {
    $env[$key] = (string)getenv($key);
}
if ($env['POC_HOST'] === '') {
    foreach (explode("\0", (string)@file_get_contents('/proc/' . $runtimePid . '/environ')) as $entry) {
        $parts = explode('=', $entry, 2);
        if (count($parts) === 2 && array_key_exists($parts[0], $env)) $env[$parts[0]] = $parts[1];
    }
}
if ($env['POC_HOST'] === '' || $env['POC_PORT'] === '' || $env['POC_SCHEMA'] === ''
    || $env['POC_USER'] === '' || $env['POC_PASSWORD'] === '') {
    throw new RuntimeException('DM runtime connection context absent');
}
$db = new PDO('dm:host=' . $env['POC_HOST'] . ';port=' . $env['POC_PORT']
    . ';schema=' . $env['POC_SCHEMA'], $env['POC_USER'], $env['POC_PASSWORD'],
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER,
        PDO::ATTR_TIMEOUT => 5]);
unset($env);
$table = static function (string $name): string { return 'YDY_' . strtoupper($name); };
$rows = static function (string $sql, array $args = []) use ($db): array {
    $query = $db->prepare($sql);
    $query->execute($args);
    return $query->fetchAll(PDO::FETCH_ASSOC);
};
$one = static function (string $sql, array $args = []) use ($rows): array {
    return $rows($sql, $args)[0] ?? [];
};
$count = static function (string $sql, array $args = []) use ($one): int {
    return (int)($one($sql, $args)['n'] ?? -1);
};
$assert = static function (bool $ok, string $message): void {
    if (!$ok) throw new RuntimeException($message);
};
$post = static function (string $route, array $form, string $token = '') use ($base): array {
    $headers = "Content-Type: application/x-www-form-urlencoded\r\n";
    if ($token !== '') $headers .= 'token: ' . $token . "\r\n";
    $context = stream_context_create(['http' => [
        'method' => 'POST', 'header' => $headers,
        'content' => http_build_query($form, '', '&', PHP_QUERY_RFC3986),
        'timeout' => 20, 'ignore_errors' => true,
    ]]);
    $body = @file_get_contents($base . $route, false, $context);
    $responseHeaders = $http_response_header ?? [];
    preg_match('/HTTP\/\S+\s+(\d+)/', (string)($responseHeaders[0] ?? ''), $match);
    $json = is_string($body) ? json_decode($body, true) : null;
    return ['http' => isset($match[1]) ? (int)$match[1] : 0,
        'json' => is_array($json) ? $json : null];
};
$pass = static function (array $response, int $businessCode = 0): bool {
    return $response['http'] === 200 && is_array($response['json'])
        && (int)($response['json']['code'] ?? -1) === $businessCode;
};

$required = [
    'YDY_STATION' => ['ID', 'UUID', 'NAME', 'STATUS', 'QUANTITY', 'DEMO', 'CREATE_BY', 'CREATE_TIME'],
    'YDY_STATION_ARCHIVE' => ['ID', 'STATION_UUID', 'ARCHIVE_UUID'],
    'YDY_ARCHIVE' => ['UUID', 'NAME'],
    'YDY_STAFF' => ['UUID', 'STATION_UUID', 'IS_SHOW'],
    'YDY_USER' => ['ID', 'UUID', 'ACCOUNT', 'PWD', 'SALT', 'NAME', 'TYPE',
        'CREATE_TIME', 'CREATE_BY', 'IS_DELETE'],
];
$metadata = [];
foreach ($required as $name => $columns) {
    $actual = $rows('SELECT COLUMN_NAME,DATA_TYPE,NULLABLE,DATA_DEFAULT FROM USER_TAB_COLUMNS'
        . ' WHERE TABLE_NAME=?', [$name]);
    $names = array_column($actual, 'column_name');
    $assert(count(array_diff($columns, $names)) === 0, 'Required DM station table columns absent: ' . $name);
    $metadata[$name] = ['required_columns_present' => true,
        'column_count' => count($actual),
        'index_count' => $count('SELECT COUNT(*) N FROM USER_INDEXES WHERE TABLE_NAME=?', [$name])];
}
$stationMeta = [];
foreach ($rows('SELECT COLUMN_NAME,NULLABLE,DATA_DEFAULT FROM USER_TAB_COLUMNS'
    . ' WHERE TABLE_NAME=? AND COLUMN_NAME IN (?,?,?,?)',
    ['YDY_STATION', 'STATUS', 'QUANTITY', 'NAME', 'CREATE_BY']) as $item) {
    $stationMeta[(string)$item['column_name']] = [
        'nullable' => (string)$item['nullable'],
        'has_default' => $item['data_default'] !== null,
    ];
}
$assert(($stationMeta['STATUS']['has_default'] ?? false)
    && ($stationMeta['QUANTITY']['has_default'] ?? false),
    'Station status/quantity defaults absent');
if ((string)getenv('POC_PREFLIGHT_ONLY') === '1') {
    echo json_encode(['suite' => 'store-station-c', 'mode' => 'read-only-preflight',
        'isolated' => true, 'tables' => $metadata, 'station_defaults' => $stationMeta,
        'existing_marker_station_rows' => $count('SELECT COUNT(*) N FROM ' . $table('station')
            . ' WHERE NAME LIKE ?', ['CDXPARSTAT%']),
        'existing_marker_operator_rows' => $count('SELECT COUNT(*) N FROM ' . $table('user')
            . ' WHERE ACCOUNT LIKE ?', ['CDXPARSTAT%'])], JSON_UNESCAPED_SLASHES) . PHP_EOL;
    exit(0);
}

require_once $root . '/application/base/Security.php';
$marker = 'CDXPARSTAT' . strtoupper(bin2hex(random_bytes(4)));
$nameA = $marker . 'A';
$nameB = $marker . 'B';
$operatorId = 0;
$stationId = 0;
$stationUuid = '';
$results = [];
$cleanup = [];
$failure = '';
try {
    $assert($count('SELECT COUNT(*) N FROM ' . $table('station') . ' WHERE NAME IN (?,?)',
        [$nameA, $nameB]) === 0, 'Synthetic station marker already present');
    $assert($count('SELECT COUNT(*) N FROM ' . $table('user')
        . ' WHERE UUID=? OR ACCOUNT=?', [$marker, $marker]) === 0,
        'Synthetic operator marker already present');
    $results['marker_before_zero'] = true;

    $unauth = $post('/p/station/add', ['name' => $nameA]);
    $assert($pass($unauth, 100)
        && $count('SELECT COUNT(*) N FROM ' . $table('station') . ' WHERE NAME=?', [$nameA]) === 0,
        'Unauthenticated station add not rejected without write');
    $results['unauth_add_rejected_zero_write'] = true;

    $insert = $db->prepare('INSERT INTO ' . $table('user')
        . ' (UUID,ACCOUNT,PWD,SALT,NAME,TYPE,CREATE_TIME,CREATE_BY,IS_DELETE)'
        . ' VALUES (?,?,?,?,?,?,?,?,?)');
    $insert->execute([$marker, $marker, 'DISABLED', strtoupper(bin2hex(random_bytes(8))),
        $marker, 0, date('Y-m-d H:i:s'), 'CODEX', 0]);
    $operatorId = (int)($one('SELECT ID FROM ' . $table('user')
        . ' WHERE UUID=? AND ACCOUNT=?', [$marker, $marker])['id'] ?? 0);
    $assert($operatorId > 0, 'Synthetic operator row missing');
    $token = \app\base\Security::encrypt(implode("\t",
        ['0', $marker, $marker, '0', '', '', $marker]));

    $invalid = $post('/p/station/add', ['name' => ''], $token);
    $assert($pass($invalid, 1)
        && $count('SELECT COUNT(*) N FROM ' . $table('station') . ' WHERE NAME=?', [$nameA]) === 0,
        'Missing station name not rejected without write');
    $results['missing_name_rejected_zero_write'] = true;

    $add = $post('/p/station/add', ['name' => $nameA, 'demo' => $marker], $token);
    $assert($pass($add), 'Station add HTTP/business response failed');
    $owned = $rows('SELECT ID,UUID,NAME,STATUS,QUANTITY,DEMO,CREATE_BY FROM ' . $table('station')
        . ' WHERE NAME=? AND CREATE_BY=?', [$nameA, $marker]);
    $assert(count($owned) === 1, 'Station add source row not unique');
    $station = $owned[0];
    $stationId = (int)$station['id'];
    $stationUuid = trim((string)$station['uuid']);
    $assert($stationId > 0 && $stationUuid !== '' && (int)$station['status'] === 1
        && (int)$station['quantity'] === 0 && (string)$station['demo'] === $marker,
        'Station add source values differ');
    $assert($count('SELECT COUNT(*) N FROM ' . $table('staff')
        . ' WHERE STATION_UUID=?', [$stationUuid]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $table('station_archive')
            . ' WHERE STATION_UUID=?', [$stationUuid]) === 0,
        'New station unexpectedly referenced');
    $results['add_source_readback_and_zero_links'] = true;

    $info = $post('/p/station/info', ['uuid' => $stationUuid], $token);
    $infoData = $info['json']['data'] ?? null;
    $assert($pass($info) && is_array($infoData)
        && trim((string)($infoData['uuid'] ?? '')) === $stationUuid
        && (string)($infoData['name'] ?? '') === $nameA
        && (int)($infoData['status'] ?? -1) === 1,
        'Station info response diverged from source');
    $results['info_contract_source_match'] = true;

    $list = $post('/p/station/lists', ['name' => $nameA, 'page' => 1], $token);
    $data = $list['json']['data'] ?? null;
    $listRows = is_array($data) ? ($data['rows'] ?? null) : null;
    $assert($pass($list) && is_array($listRows) && count($listRows) === 1
        && (int)($data['total'] ?? -1) === 1
        && trim((string)($listRows[0]['uuid'] ?? '')) === $stationUuid
        && (string)($listRows[0]['name'] ?? '') === $nameA
        && (int)($listRows[0]['quantity'] ?? -1) === 0
        && (int)($listRows[0]['is_quote'] ?? -1) === 0,
        'Station list response diverged from source/zero staff');
    $results['lists_filtered_source_match_zero_staff'] = true;

    $update = $post('/p/station/update', ['uuid' => $stationUuid,
        'name' => $nameB, 'demo' => $marker . 'B'], $token);
    $updated = $one('SELECT ID,UUID,NAME,STATUS,DEMO FROM ' . $table('station')
        . ' WHERE ID=? AND UUID=?', [$stationId, $stationUuid]);
    $assert($pass($update) && (string)($updated['name'] ?? '') === $nameB
        && (string)($updated['demo'] ?? '') === $marker . 'B'
        && (int)($updated['status'] ?? -1) === 1,
        'Station update response/source mismatch');
    $results['update_own_name_source_readback'] = true;

    $assert($count('SELECT COUNT(*) N FROM ' . $table('staff')
        . ' WHERE STATION_UUID=?', [$stationUuid]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $table('station_archive')
            . ' WHERE STATION_UUID=?', [$stationUuid]) === 0,
        'Station unexpectedly linked before status toggle');
    $off = $post('/p/station/able', ['uuid' => $stationUuid], $token);
    $offRow = $one('SELECT STATUS FROM ' . $table('station')
        . ' WHERE ID=? AND UUID=?', [$stationId, $stationUuid]);
    $assert($pass($off) && (int)($offRow['status'] ?? -1) === 0,
        'Station disable response/source mismatch');
    $results['able_disable_own_status'] = true;
    $on = $post('/p/station/able', ['uuid' => $stationUuid], $token);
    $onRow = $one('SELECT STATUS FROM ' . $table('station')
        . ' WHERE ID=? AND UUID=?', [$stationId, $stationUuid]);
    $assert($pass($on) && (int)($onRow['status'] ?? -1) === 1,
        'Station enable response/source mismatch');
    $results['able_enable_own_status'] = true;

    $assert($count('SELECT COUNT(*) N FROM ' . $table('staff')
        . ' WHERE STATION_UUID=?', [$stationUuid]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $table('station_archive')
            . ' WHERE STATION_UUID=?', [$stationUuid]) === 0,
        'Station linked before delete; refusing delete');
    $delete = $post('/p/station/delete', ['uuid' => $stationUuid], $token);
    $assert($pass($delete)
        && $count('SELECT COUNT(*) N FROM ' . $table('station')
            . ' WHERE ID=? AND UUID=?', [$stationId, $stationUuid]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $table('station_archive')
            . ' WHERE STATION_UUID=?', [$stationUuid]) === 0,
        'Station delete response/source mismatch');
    $results['delete_own_station_and_link_zero'] = true;
} catch (Throwable $e) {
    $failure = get_class($e) . ':' . hash('sha256', $e->getMessage());
} finally {
    try {
        $owned = $rows('SELECT ID,UUID,NAME,CREATE_BY FROM ' . $table('station')
            . ' WHERE NAME IN (?,?) AND CREATE_BY=?', [$nameA, $nameB, $marker]);
        if (count($owned) > 1) throw new RuntimeException('Ambiguous station cleanup');
        if (count($owned) === 1) {
            $item = $owned[0];
            $id = (int)$item['id'];
            $uuid = trim((string)$item['uuid']);
            if ($stationId > 0 && ($id !== $stationId || $uuid !== $stationUuid)) {
                throw new RuntimeException('Station identity changed before cleanup');
            }
            if ($count('SELECT COUNT(*) N FROM ' . $table('staff') . ' WHERE STATION_UUID=?', [$uuid]) !== 0
                || $count('SELECT COUNT(*) N FROM ' . $table('station_archive')
                    . ' WHERE STATION_UUID=?', [$uuid]) !== 0) {
                throw new RuntimeException('Station referenced; refusing exact cleanup');
            }
            $statement = $db->prepare('DELETE FROM ' . $table('station')
                . ' WHERE ID=? AND UUID=? AND NAME=? AND CREATE_BY=?');
            $statement->execute([$id, $uuid, (string)$item['name'], $marker]);
        }
        if ($operatorId > 0) {
            $statement = $db->prepare('DELETE FROM ' . $table('user')
                . ' WHERE ID=? AND UUID=? AND ACCOUNT=?');
            $statement->execute([$operatorId, $marker, $marker]);
        }
        $cleanup = [
            'operator_zero' => $count('SELECT COUNT(*) N FROM ' . $table('user')
                . ' WHERE UUID=? OR ACCOUNT=?', [$marker, $marker]) === 0,
            'station_zero' => $count('SELECT COUNT(*) N FROM ' . $table('station')
                . ' WHERE NAME IN (?,?)', [$nameA, $nameB]) === 0,
            'staff_link_zero' => $stationUuid === '' || $count('SELECT COUNT(*) N FROM ' . $table('staff')
                . ' WHERE STATION_UUID=?', [$stationUuid]) === 0,
            'archive_link_zero' => $stationUuid === '' || $count('SELECT COUNT(*) N FROM ' . $table('station_archive')
                . ' WHERE STATION_UUID=?', [$stationUuid]) === 0,
        ];
    } catch (Throwable $e) {
        $cleanup['error_class'] = get_class($e);
        $cleanup['error_sha256'] = hash('sha256', $e->getMessage());
    }
}
$clean = ($cleanup['operator_zero'] ?? false) && ($cleanup['station_zero'] ?? false)
    && ($cleanup['staff_link_zero'] ?? false) && ($cleanup['archive_link_zero'] ?? false);
echo json_encode(['suite' => 'store-station-c', 'dialect' => 'dm', 'isolated' => true,
    'marker' => $marker, 'results' => $results, 'failure' => $failure, 'cleanup' => $cleanup],
    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
if ($failure !== '' || !$clean) exit(1);
