<?php
declare(strict_types=1);

$dialect = (string)getenv('POC_DIALECT');
$base = rtrim((string)getenv('POC_BASE_URL'), '/');
if (!in_array($dialect, ['mysql', 'dm'], true) || !preg_match('#^http://127\.0\.0\.1:\d+$#', $base)) exit(2);
$boundary = json_decode((string)file_get_contents($base . '/__poc_boundary'), true);
if (empty($boundary['external_stubs'])) throw new RuntimeException('Unapproved HTTP boundary');
if ($dialect === 'mysql') {
    $file = (string)getenv('POC_ENV_FILE');
    if (basename($file) !== '.env.local' || !is_file($file)) exit(2);
    $config = parse_ini_file($file, true, INI_SCANNER_RAW)['DATABASE'];
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT', 'DATABASE' => 'SCHEMA', 'USERNAME' => 'USER', 'PASSWORD' => 'PASSWORD'] as $from => $to) {
        putenv('POC_AI_' . $to . '=' . $config[$from]);
    }
}
$host = getenv('POC_AI_HOST'); $port = getenv('POC_AI_PORT'); $schema = getenv('POC_AI_SCHEMA');
$pdo = new PDO($dialect === 'dm' ? "dm:host=$host;port=$port;schema=$schema"
    : "mysql:host=$host;port=$port;dbname=$schema;charset=utf8mb4",
    getenv('POC_AI_USER'), getenv('POC_AI_PASSWORD'), [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_TIMEOUT => 5]);
$table = $dialect === 'dm' ? 'YOSHOP_CONFIG_ENUM' : 'yoshop_config_enum';
$order = $dialect === 'dm' ? '"ORDER"' : '`order`';
$metadata = $pdo->query($dialect === 'dm'
    ? "SELECT DATA_TYPE,DATA_PRECISION,DATA_SCALE FROM USER_TAB_COLUMNS WHERE TABLE_NAME='YOSHOP_CONFIG_ENUM' AND COLUMN_NAME='RATIO'"
    : "SELECT DATA_TYPE,NUMERIC_PRECISION AS DATA_PRECISION,NUMERIC_SCALE AS DATA_SCALE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='yoshop_config_enum' AND COLUMN_NAME='ratio'")->fetch(PDO::FETCH_ASSOC);
if (getenv('POC_METADATA_ONLY') === '1') {
    echo json_encode(['dialect' => $dialect, 'ratio_metadata' => $metadata]) . PHP_EOL;
    exit(0);
}
$method = getenv('POC_METHOD') === 'POST' ? 'POST' : 'GET';
$firstType = max(1, min(17, (int)(getenv('POC_ENUM_FROM') ?: 1)));
$result = []; $error = null;
try {
    foreach (range($firstType, 17) as $enumType) {
        $q = $pdo->prepare('SELECT * FROM ' . $table . ' WHERE ENUM_TYPE=? AND IS_DELETE=0 ORDER BY ' . $order);
        $q->execute([$enumType]); $source = $q->fetchAll(PDO::FETCH_ASSOC);
        $sourceByKey = [];
        foreach ($source as $row) $sourceByKey[(string)$row['enum_key']] = $row;
        $started = microtime(true);
        $args = http_build_query(['storeId' => 10001, 'enumType' => $enumType]);
        $raw = file_get_contents($base . '/api/enum/all' . ($method === 'GET' ? '?' . $args : ''),
            false, stream_context_create(['http' => ['method' => $method, 'timeout' => 15, 'ignore_errors' => true,
                'header' => 'Content-Type: application/x-www-form-urlencoded', 'content' => $method === 'POST' ? $args : '']]));
        $response = is_string($raw) ? json_decode($raw, true) : null;
        preg_match('#^HTTP/\S+\s+(\d+)#', $http_response_header[0] ?? '', $httpMatch);
        $httpCode = isset($httpMatch[1]) ? (int)$httpMatch[1] : null;
        $list = $response['data']['list'] ?? null;
        $pass = $httpCode === 200 && ($response['status'] ?? null) === 200 && is_array($list) && count($list) === count($source);
        $types = [];
        if ($pass) foreach ($list as $item) {
            $row = $sourceByKey[(string)($item['enum_key'] ?? '')] ?? null;
            if (!$row) { $pass = false; break; }
            foreach ($item as $key => $value) {
                $types[$key][gettype($value)] = true;
                if (!array_key_exists($key, $row)) { $pass = false; break; }
                $expected = $row[$key];
                if (is_resource($expected)) $expected = stream_get_contents($expected);
                if (is_numeric($expected) && is_numeric($value)) {
                    if (bccomp((string)$expected, (string)$value, 10) !== 0) $pass = false;
                } elseif ($expected !== $value) $pass = false;
            }
        }
        ksort($types); foreach ($types as &$t) { $t = array_keys($t); sort($t); } unset($t);
        $result[] = ['enum_type' => $enumType, 'source_rows' => count($source),
            'http_status' => $httpCode, 'business_status' => $response['status'] ?? null, 'source_values_equal' => $pass,
            'types' => $types, 'elapsed_ms' => round((microtime(true) - $started) * 1000)];
        if (!$pass) break;
    }
} catch (Throwable $e) {
    $error = ['type' => get_class($e), 'code' => (string)$e->getCode()];
}
echo json_encode(['dialect' => $dialect, 'method' => $method, 'ratio_metadata' => $metadata, 'read_only' => true, 'cases' => $result,
    'error' => $error], JSON_UNESCAPED_UNICODE) . PHP_EOL;
exit($error !== null || count($result) !== 18 - $firstType || in_array(false, array_column($result, 'source_values_equal'), true) ? 1 : 0);
