<?php

declare(strict_types=1);

// Reads two approved loopback endpoints; retains response bodies only in process memory.
$variant = (string)getenv('POC_VARIANT');
$runtime = [
    'B' => ['base' => 'http://127.0.0.1:18101',
        'root' => '/tmp/zhct-http-ai-macos.x2CCZX', 'pid' => 13127,
        'source' => '/tmp/zhct-http-ai-macos.x2CCZX/app/api/service/Setting.php',
        'autoload_source' => '/Users/wiscourper/Documents/workspace/local/dm8-full-acceptance.fF5yTy/ai_api/app/api/service/Setting.php'],
    'C' => ['base' => 'http://127.0.0.1:18102',
        'root' => '/tmp/zhct-ai-http-20260929.3XDj3w', 'pid' => 53772,
        'source' => '/tmp/zhct-ai-http-20260929.3XDj3w/app/api/service/Setting.php',
        'autoload_source' => '/tmp/zhct-dm-poc-20260928.fcpiiN/ai_api/app/api/service/Setting.php'],
];
if (!isset($runtime[$variant])) throw new RuntimeException('Only B/C isolated runtime allowed');
$expectedSha = '7543d783d8695481544a3326f5ea7c555a0ea1a4250670160dd02b0d992ecb65';
if (!is_file($runtime[$variant]['source'])
    || hash_file('sha256', $runtime[$variant]['source']) !== $expectedSha
    || hash_file('sha256', $runtime[$variant]['autoload_source']) !== $expectedSha) {
    throw new RuntimeException('Public setting filter not deployed to isolated HTTP copy');
}
$pid = $runtime[$variant]['pid'];
if ($variant === 'C') {
    $env = [];
    foreach (explode("\0", (string)@file_get_contents('/proc/' . $pid . '/environ')) as $item) {
        $parts = explode('=', $item, 2);
        if (count($parts) === 2) $env[$parts[0]] = $parts[1];
    }
    if (($env['POC_TARGET_ROOT'] ?? '') !== $runtime[$variant]['root']
        || ($env['POC_BASE_URL'] ?? '') !== $runtime[$variant]['base']
        || ($env['POC_DIALECT'] ?? '') !== 'dm'
        || ($env['POC_AI_HOST'] ?? '') !== '127.0.0.1'
        || ($env['POC_AI_PORT'] ?? '') !== '5238'
        || ($env['POC_AI_SCHEMA'] ?? '') !== 'AIZHCT_APP'
        || ($env['POC_AI_USER'] ?? '') !== 'AIZHCT_APP'
        || ($env['POC_HOST'] ?? '') !== '127.0.0.1'
        || ($env['POC_PORT'] ?? '') !== '5237'
        || ($env['POC_SCHEMA'] ?? '') !== 'ZHCT_APP'
        || ($env['POC_USER'] ?? '') !== 'ZHCT_APP') {
        throw new RuntimeException('C dual-business non-production identity mismatch');
    }
} else {
    $path = '/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local';
    $local = parse_ini_file($path, true, INI_SCANNER_RAW);
    $listener = trim((string)shell_exec('lsof -nP -iTCP:18101 -sTCP:LISTEN -t 2>/dev/null'));
    $process = (string)shell_exec('ps eww -p ' . $pid . ' -o command=');
    if ($listener !== (string)$pid || !is_array($local)
        || !isset($local['DATABASE'], $local['DATABASE_ZHCT'])
        || strpos($process, $runtime[$variant]['root'] . '/public') === false) {
        throw new RuntimeException('B HTTP/local boundary absent');
    }
    $expected = ['POC_TARGET_ROOT' => $runtime[$variant]['root'],
        'POC_BASE_URL' => $runtime[$variant]['base'], 'POC_DIALECT' => 'mysql'];
    foreach (['DATABASE' => 'POC_AI_', 'DATABASE_ZHCT' => 'POC_'] as $section => $prefix) {
        foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT',
            'DATABASE' => 'SCHEMA', 'USERNAME' => 'USER',
            'PASSWORD' => 'PASSWORD'] as $from => $to) {
            $expected[$prefix . $to] = (string)$local[$section][$from];
        }
    }
    foreach ($expected as $key => $value) {
        $pattern = '/(?:^|\\s)' . preg_quote($key, '/') . '=([^\\s]*)/';
        if (!preg_match($pattern, $process, $match) || $match[1] !== $value) {
            throw new RuntimeException('B HTTP process differs from code local DB configuration');
        }
    }
}
$base = $runtime[$variant]['base'];
$boundaryRaw = @file_get_contents($base . '/__poc_boundary', false,
    stream_context_create(['http' => ['timeout' => 5]]));
$boundary = is_string($boundaryRaw) ? json_decode($boundaryRaw, true) : null;
unset($boundaryRaw);
if (!is_array($boundary) || empty($boundary['external_stubs'])) {
    throw new RuntimeException('External isolation absent');
}

$isSecretName = static function (string $key): bool {
    $lower = strtolower($key);
    if (in_array($lower, ['force_change_password', 'api_key_remark'], true)) return false;
    if (in_array($lower, ['password', 'secret', 'token', 'private_key', 'api_key',
        'client_secret', 'access_key_secret', 'secret_key', 'secret_id',
        'accesskeysecret', 'secretkey'], true)) return true;
    return (bool)preg_match('/(?:^|_)(?:password|secret|token|private_key)$/i', $key);
};
$scanNames = static function ($data, string $prefix = '') use (&$scanNames, $isSecretName): array {
    if (!is_array($data)) return [];
    $found = [];
    foreach ($data as $key => $value) {
        if (!is_string($key)) continue;
        $path = $prefix === '' ? $key : $prefix . '.' . $key;
        if ($isSecretName($key)) $found[] = $path;
        if (is_array($value)) {
            foreach ($scanNames($value, $path) as $nested) $found[] = $nested;
        }
    }
    return array_values(array_unique($found));
};

$results = [];
foreach (['setting/data', 'store/data'] as $endpoint) {
    $url = $base . '/api/' . $endpoint . '?storeId=10001';
    $raw = @file_get_contents($url, false, stream_context_create([
        'http' => ['method' => 'GET', 'header' => "platform: POC\r\nConnection: close\r\n",
            'timeout' => 15, 'ignore_errors' => true],
    ]));
    preg_match('/HTTP\/\S+\s+(\d+)/', $http_response_header[0] ?? '', $httpMatch);
    $json = is_string($raw) ? json_decode($raw, true) : null;
    unset($raw);
    $setting = is_array($json) ? ($endpoint === 'setting/data'
        ? ($json['data']['setting'] ?? null)
        : ($json['data']['setting'] ?? null)) : null;
    $aiConfig = is_array($setting) ? ($setting['aiConfig'] ?? null) : null;
    $sensitivePaths = $scanNames($json);
    $results[$endpoint] = [
        'http' => (int)($httpMatch[1] ?? 0),
        'business_status' => is_array($json) ? (int)($json['status'] ?? -1) : -1,
        'setting_is_array' => is_array($setting),
        'ai_config_is_array' => is_array($aiConfig),
        'ai_config_api_key_present' => is_array($aiConfig)
            && array_key_exists('api_key', $aiConfig),
        'other_sensitive_key_present' => count(array_filter($sensitivePaths,
            static function (string $path): bool {
                return !preg_match('/(?:^|\.)api_key$/i', $path);
            })) > 0,
        // Field names only, never values; empty in the expected safe case.
        'sensitive_key_paths' => $sensitivePaths,
    ];
    unset($json, $setting, $aiConfig, $sensitivePaths);
    $entry = $results[$endpoint];
    if ($entry['http'] !== 200 || $entry['business_status'] !== 200
        || !$entry['setting_is_array'] || !$entry['ai_config_is_array']
        || $entry['ai_config_api_key_present'] || $entry['other_sensitive_key_present']) {
        echo json_encode(['variant' => $variant, 'mode' => 'loopback-key-names-only',
            'results' => $results], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
        exit(1);
    }
}
echo json_encode(['variant' => $variant, 'mode' => 'loopback-key-names-only',
    'results' => $results], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit(0);
