<?php

namespace Application\Service\Extension\Cache;

use Application\Service\Extension\Helper\EncryptHelper;

class TagDependency implements DependencyInterface
{
    public array $tags = [];

    public function __construct(array $tags = [])
    {
        $this->tags = $tags['tags'];
    }

    private static function buildKey($key)
    {
        return 'CACHE:' . EncryptHelper::md5('tag' . $key);
    }

    /**
     * 生成依赖数据，用于更新缓存项的过期时间或添加新的缓存依赖
     *
     * @param mixed $currentKey 当前缓存项的键
     * @param int|null $duration 可选的缓存持续时间（秒），null表示不过期
     */
    public function generateDependencyData($currentKey, ?int $duration)
    {
        // 初始化过期时间为0，表示不过期
        $expireTime = 0;
        // 如果指定了持续时间，则计算绝对过期时间
        if ($duration !== null) {
            $expireTime = time() + $duration;
        }

        // 遍历所有标签，为每个标签更新或添加缓存依赖
        foreach ($this->tags as $tag) {
            // 构建标签对应的缓存键
            $key = self::buildKey($tag);
            // 获取当前时间
            $time = time();

            // 将当前缓存项添加到有序集合中，关联过期时间
            Cache::app()->getAdapter()->zAdd("{$key}", ...[$expireTime, $currentKey]);
            // 移除已经过期的缓存项依赖
            Cache::app()->getAdapter()->zRemRangeByScore("$key", 1, $time);

            // 设置tag分组的ttl
            if ($ttl = Cache::app()->getAdapter()->ttl($key)) {
                // 如果当前设置的过期时间晚于已有的TTL，并且duration大于0，则更新过期时间
                if ($expireTime > 0 && $expireTime > $ttl + $time && $duration > 0) {
                    Cache::app()->getAdapter()->expire($key, $duration);
                }
            }
        }
    }

    public static function invalid($tagName)
    {
//        var_dump(Cache::app()->getAdapter()->zRange("CACHE:TAG:$tagName", 0, -1));die;
        $tags = array_values(Cache::app()->getAdapter()->zRange(self::buildKey($tagName), 0, -1));
        if ($tags) {
            array_push($tags, self::buildKey($tagName));
            Cache::app()->delete($tags);
        }
    }
}