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

use Core\service\BaseCoreService;
use GuzzleHttp\Client;
use think\facade\Log;


/**
 * 升级检查器
 * @package app\service\domain\upgrade
 */
class UpgradeChecker extends BaseCoreService
{
    private UpgradeTokenService $tokenService;

    /**
     * 构造函数
     * @param \think\App $app 应用实例
     * @param UpgradeTokenService $tokenService 升级令牌服务
     */
    public function __construct(\think\App $app, UpgradeTokenService $tokenService)
    {
        parent::__construct($app);
        $this->tokenService = $tokenService;
    }


    /**
     * 检查远程升级
     * @param string $fromVersion 从版本号
     * @return array|null 升级信息
     */
    public function checkRemote(string $fromVersion = ''): ?array
    {
        $config = $this->tokenService->remoteConfig();
        $apiUrl = $config['api_url'];

        if ($apiUrl === '') {
            Log::warning('upgrade: remote_api_url not configured');
            return null;
        }

        $url = rtrim($apiUrl, '/') . '?action=check';
        if ($fromVersion !== '') {
            $url .= '&from_version=' . urlencode($fromVersion);
        }
        $client = new Client(['timeout' => 15]);

        try {
            $response = $client->get($url);
            $body = json_decode((string)$response->getBody(), true);

            if (!isset($body['code']) || $body['code'] !== 0) {
                Log::error('upgrade check failed: ' . ($body['message'] ?? 'unknown'));
                return null;
            }

            return $body['data'] ?? null;
        } catch (\Throwable $e) {
            Log::error('upgrade check exception: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 获取当前版本
     * @return array 当前版本信息
     */
    public function currentVersion(): array
    {
        $frameworkVersion = '1.0.0';


        $coreManifestFile = app()->getRootPath() . 'core/manifest/manifest.json';
        $manifest = $this->readJsonFile($coreManifestFile);
        if (!empty($manifest['version'])) {
            $frameworkVersion = (string)$manifest['version'];
        }


        $applications = [];
        $applicationsDir = app()->getRootPath() . 'applications/';
        if (is_dir($applicationsDir)) {
            $dirs = scandir($applicationsDir);
            foreach ($dirs as $dir) {
                if ($dir === '.' || $dir === '..') {
                    continue;
                }
                $manifestFile = $applicationsDir . $dir . '/manifest.json';
                $manifest = $this->readJsonFile($manifestFile);
                $applications[$dir] = (string)($manifest['version'] ?? '1.0.0');
            }
        }

        return [
            'version' => $frameworkVersion,
            'framework' => ['version' => $frameworkVersion],
            'applications' => $applications,
        ];
    }

    /**
     * 读取 JSON 文件
     * @param string $file 文件路径
     * @return array JSON 数据
     */
    private function readJsonFile(string $file): array
    {
        if (!file_exists($file)) {
            return [];
        }

        $content = file_get_contents($file);
        if (!is_string($content) || $content === '') {
            return [];
        }

        $content = preg_replace('/^\xEF\xBB\xBF/', '', $content) ?? $content;
        $data = json_decode($content, true);

        return is_array($data) ? $data : [];
    }
}