<?php
declare(strict_types=1);

const CAT8F_LIB_SHA = '6f88a6e9a43cebb1f51af7bcd65781c54497205f2785dbb32c936f6fdb941326';
const CAT8F_MODE = 'synthetic_super_catalog_read';
const CAT8F_STORE_ID = 10001;

$shared = __DIR__ . '/../parallel-ai-route-triage-20261002/catalog8_fixture_lib.draft.php';
if (!hash_equals(CAT8F_LIB_SHA, (string)hash_file('sha256', $shared))) {
    throw new RuntimeException('Pinned runtime-boundary library changed');
}
require $shared;

function cat8f_manifest(): array
{
    $data = cat8_manifest((string)getenv('CDX_CAT8F_MANIFEST'));
    if (($data['fixture_mode'] ?? null) !== CAT8F_MODE
        || (int)($data['store_id'] ?? 0) !== CAT8F_STORE_ID) {
        throw new RuntimeException('Synthetic-super manifest mismatch');
    }
    return $data;
}

function cat8f_operator(PDO $db, string $marker): array
{
    return cat8_rows($db, 'SELECT STORE_USER_ID,USER_NAME,REAL_NAME,IS_SUPER,'
        . 'IS_DELETE,STORE_ID FROM yoshop_store_user WHERE USER_NAME=? AND STORE_ID=10001',
        [$marker]);
}

function cat8f_owned(array $row, array $data): bool
{
    return (string)$row['user_name'] === $data['user_name']
        && (string)$row['real_name'] === $data['user_name']
        && (int)$row['store_id'] === CAT8F_STORE_ID
        && (int)$row['is_super'] === 1 && (int)$row['is_delete'] === 0
        && ((int)($data['store_user_id'] ?? 0) === 0
            || (int)$row['store_user_id'] === (int)$data['store_user_id']);
}

function cat8f_refs(PDO $db, int $userId): array
{
    return [
        'user_role' => cat8_count($db,
            'SELECT COUNT(*) FROM yoshop_store_user_role WHERE STORE_USER_ID=?', [$userId]),
        'user_relation' => cat8_count($db,
            'SELECT COUNT(*) FROM yoshop_store_user_relation'
            . ' WHERE STORE_USER_ID=? OR RELATION_STORE_USER_ID=?', [$userId, $userId]),
        'staff_relation' => cat8_count($db,
            'SELECT COUNT(*) FROM yoshop_staff_store_user WHERE STORE_USER_ID=?', [$userId]),
    ];
}

function cat8f_session(array $data, int $userId): array
{
    return ['user' => [
        'store_user_id' => $userId, 'store_id' => CAT8F_STORE_ID,
        'user_name' => $data['user_name'], 'real_name' => $data['user_name'],
        'is_super' => 1, 'is_delete' => 0,
    ], 'store_id' => CAT8F_STORE_ID, 'is_login' => true];
}

function cat8f_cache_state(array $data): array
{
    $path = \think\facade\Cache::store('file')->getCacheKey($data['token']);
    if (!is_file($path)) return ['exists' => false, 'live' => false];
    $header = (string)file_get_contents($path, false, null, 0, 32);
    clearstatcache(true, $path);
    $mtime = filemtime($path);
    if (!preg_match('/^<\?php\n\/\/(\d{12})\n/', $header, $match)
        || $mtime === false || (int)$match[1] !== 300) {
        return ['exists' => true, 'live' => false, 'ttl_valid' => false];
    }
    $expires = $mtime + 300;
    $live = $expires > time() + 2;
    // Think File Cache deletes an expired file on get(). Do not call it here.
    $value = $live ? \think\facade\Cache::get($data['token']) : null;
    return ['exists' => true, 'live' => $live,
        'ttl_valid' => $expires === (int)($data['expires_at'] ?? 0),
        'expires_at' => $expires, 'session' => $value];
}

function cat8f_approved(string $constant, string $file): void
{
    if (!hash_equals($constant, (string)getenv('CDX_CAT8F_APPROVAL'))) {
        echo json_encode(['status' => 'default_deny', 'database_connected' => false,
            'cache_accessed' => false, 'business_http_sent' => false,
            'dml_sent' => false]), PHP_EOL;
        exit(78);
    }
    if (!hash_equals((string)hash_file('sha256', $file),
            (string)getenv('CDX_CAT8F_SCRIPT_SHA256'))
        || !hash_equals((string)hash_file('sha256', __FILE__),
            (string)getenv('CDX_CAT8F_COMMON_SHA256'))
        || !hash_equals((string)hash_file('sha256', __DIR__ . '/contract.php'),
            (string)getenv('CDX_CAT8F_CONTRACT_SHA256'))) {
        throw new RuntimeException('Exact reviewed source SHAs required');
    }
}
