<?php
if (!function_exists("noc_cache_dir")) {
function noc_cache_dir(): string {
    $dir = dirname(__DIR__) . '/cache';
    if (!is_dir($dir)) { @mkdir($dir, 0777, true); }
    return $dir;
}
function noc_cache_file(string $name): string { return noc_cache_dir() . '/' . $name . '.json'; }
function noc_lock_file(string $name): string { return noc_cache_dir() . '/' . $name . '.lock'; }
function noc_load_json_file(string $path, $default = null) {
    if (!is_file($path)) return $default;
    $raw = @file_get_contents($path);
    $data = json_decode((string)$raw, true);
    return is_array($data) ? $data : $default;
}
function noc_save_json_file(string $path, array $data): void {
    @file_put_contents($path, json_encode($data, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES), LOCK_EX);
}
function noc_try_lock(string $name) {
    $fp = @fopen(noc_lock_file($name), 'c+');
    if (!$fp) return false;
    if (!@flock($fp, LOCK_EX | LOCK_NB)) { @fclose($fp); return false; }
    return $fp;
}
function noc_unlock($fp): void {
    if (is_resource($fp)) { @flock($fp, LOCK_UN); @fclose($fp); }
}
function noc_json_response(array $out, int $code=200): void {
    http_response_code($code);
    while (ob_get_level() > 0) { @ob_end_clean(); }
    echo json_encode($out, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    exit;
}
}
