<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\service\domain\queue;

use Core\contract\ConfigStoreInterface;
use think\facade\Config;


/**
 * Queue Config Service
 * @package app\service\domain\queue
 */
class QueueConfigService
{
     /**
      * 队列配置服务
      * @package app\service\domain\queue
      */
    private ConfigStoreInterface $configStore;

     /**
      * 队列配置服务构造函数
      * @param ConfigStoreInterface $configStore 配置存储接口
      */
    public function __construct(ConfigStoreInterface $configStore)
    {
        $this->configStore = $configStore;
    }

     /**
      * 队列配置服务是否启用
      * @return bool
      */
    public function isEnabled(): bool
    {
        $default = (bool)Config::get('queue.enabled', false);
        return $this->configStore->getInt('queue_enabled', $default ? 1 : 0) === 1;
    }

     /**
      * 队列配置服务驱动
      * @return string
      */
    public function driver(): string
    {
        $driver = trim($this->configStore->getString('queue_driver', (string)Config::get('queue.driver', 'sync')));
        return in_array($driver, ['sync', 'database', 'redis'], true) ? $driver : 'sync';
    }

     /**
      * 队列配置服务默认队列
      * @return string
      */
    public function defaultQueue(): string
    {
        $value = trim($this->configStore->getString('queue_default_queue', (string)Config::get('queue.default_queue', 'default')));
        return $value !== '' ? $value : 'default';
    }

     /**
      * 队列配置服务重试延迟秒数
      * @return int
      */
    public function retryDelaySeconds(): int
    {
        return $this->boundedInt('queue_retry_delay_seconds', (int)Config::get('queue.retry_delay_seconds', 60), 1, 86400);
    }

     /**
      * 队列配置服务保留秒数
      * @return int
      */
    public function reserveSeconds(): int
    {
        return $this->boundedInt('queue_reserve_seconds', (int)Config::get('queue.reserve_seconds', 120), 5, 86400);
    }

     /**
      * 队列配置服务最大重试次数
      * @return int
      */
    public function maxAttempts(): int
    {
        return $this->boundedInt('queue_max_attempts', (int)Config::get('queue.max_attempts', 5), 1, 20);
    }

     /**
      * 队列配置服务工作睡眠秒数
      * @return int
      */
    public function workSleepSeconds(): int
    {
        return $this->boundedInt('queue_work_sleep_seconds', (int)Config::get('queue.work_sleep_seconds', 3), 1, 60);
    }

     /**
      * 队列配置服务是否回退到同步模式
      * @return bool
      */
    public function fallbackToSync(): bool
    {
        $default = (bool)Config::get('queue.fallback_to_sync', true);
        return $this->configStore->getInt('queue_fallback_to_sync', $default ? 1 : 0) === 1;
    }


    /**
     * 获取数据库队列表名
     * @return string
     */
    public function databaseTable(): string
    {
        $table = trim((string)Config::get('queue.database.table', 'async_queue_messages'));
        return $table !== '' ? $table : 'async_queue_messages';
    }

     /**
      * 队列配置服务Redis配置
      * @return array
      */
    public function redisConfig(): array
    {
        return [
            'host' => $this->configStore->getString('queue_redis_host', (string)Config::get('queue.redis.host', '127.0.0.1')),
            'port' => $this->boundedInt('queue_redis_port', (int)Config::get('queue.redis.port', 6379), 1, 65535),
            'password' => $this->configStore->getString('queue_redis_password', (string)Config::get('queue.redis.password', '')),
            'select' => $this->boundedInt('queue_redis_select', (int)Config::get('queue.redis.select', 0), 0, 15),
            'timeout' => $this->boundedInt('queue_redis_timeout', (int)Config::get('queue.redis.timeout', 0), 0, 30),
            'persistent' => $this->configStore->getInt('queue_redis_persistent', (int)((bool)Config::get('queue.redis.persistent', false))) === 1 ? 1 : 0,
            'prefix' => $this->redisPrefix(),
        ];
    }

     /**
      * 队列配置服务快照
      * @return array
      */
    public function snapshot(): array
    {
        return [
            'enabled' => $this->isEnabled() ? 1 : 0,
            'driver' => $this->driver(),
            'default_queue' => $this->defaultQueue(),
            'retry_delay_seconds' => $this->retryDelaySeconds(),
            'reserve_seconds' => $this->reserveSeconds(),
            'max_attempts' => $this->maxAttempts(),
            'work_sleep_seconds' => $this->workSleepSeconds(),
            'fallback_to_sync' => $this->fallbackToSync() ? 1 : 0,
            'database_table' => $this->databaseTable(),
            'redis' => $this->redisConfig(),
        ];
    }

     /**
      * 队列配置服务整数配置
      * @param string $key 配置键
      * @param int $default 默认值
      * @param int $min 最小值
      * @param int $max 最大值
      * @return int
      */
    private function boundedInt(string $key, int $default, int $min, int $max): int
    {
        $value = $this->configStore->getInt($key, $default);
        if ($value < $min) {
            $value = $min;
        }
        if ($value > $max) {
            $value = $max;
        }
        return $value;
    }

     /**
      * 队列配置服务Redis前缀
      * @return string
      */
    private function redisPrefix(): string
    {
        $prefix = trim($this->configStore->getString('queue_redis_prefix', (string)Config::get('queue.redis.prefix', 'async_queue:')));
        return $prefix !== '' ? $prefix : 'async_queue:';
    }
}
