<?php

namespace Application\Service\Extension;

use Swoole\Coroutine;

class Context
{
    private static array $data = []; // 存储上下文数据

    /**
     * 获取当前协程 ID
     * @return int|null 协程 ID，如果不在协程中返回 null
     */
    private static function getCoroutineId(): ?int
    {
        return Coroutine::getCid();
    }

    /**
     * 设置上下文数据（支持多层设置）
     * @param string $key 顶层键
     * @param mixed $value 要设置的值
     * @param array|string|null $subKey 可选，子键路径（可以是数组或字符串）
     */
    public static function set(string $key, $value, $subKey = null): void
    {
        $cid = self::getCoroutineId();

        // 如果没有提供子键路径，直接设置顶层键
        if ($subKey === null) {
            self::$data[$cid][$key] = $value;
            return;
        }

        // 确保顶层键存在并为数组
        if (!isset(self::$data[$cid][$key]) || !is_array(self::$data[$cid][$key])) {
            self::$data[$cid][$key] = [];
        }

        // 通过递归方式设置多层嵌套数据
        $target = &self::$data[$cid][$key];
        foreach ((array)$subKey as $k) {
            if (!isset($target[$k]) || !is_array($target[$k])) {
                $target[$k] = [];
            }
            $target = &$target[$k];
        }
        $target = $value;
    }

    /**
     * 获取上下文数据（支持多层获取）
     * @param string $key 顶层键
     * @param array|string|null $subKey 可选，子键路径（可以是数组或字符串）
     * @param mixed $default 默认值
     * @return mixed 返回值或默认值
     */
    public static function get(string $key, $subKey = null, $default = null)
    {
        $cid = self::getCoroutineId();
        if (!isset(self::$data[$cid][$key])) {
            return $default;
        }

        // 如果没有提供子键路径，直接返回顶层数据
        if ($subKey === null) {
            return self::$data[$cid][$key];
        }

        // 递归获取嵌套数据
        $target = self::$data[$cid][$key];
        foreach ((array)$subKey as $k) {
            if (!isset($target[$k])) {
                return $default;
            }
            $target = $target[$k];
        }
        return $target;
    }
}