<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Services\Plugin;

use App\Exceptions\Plugin\HostPluginInstallException;

/**
 * 插件包解压与 plugin.json 校验的共享步骤。
 */
final class HostPluginPackageStagingHelper
{
    public function __construct(
        private readonly HostPluginManifestValidator $manifestValidator,
    ) {}

    /**
     * @return array{manifest: array<string, mixed>, plugin_root: string, alias: string}
     */
    public function validateExtractedRoot(string $stagingDirectory, string $expectedPluginCode): array
    {
        $pluginRoot = $this->resolveExtractedPluginRoot($stagingDirectory);
        $manifestPath = $pluginRoot.DIRECTORY_SEPARATOR.'plugin.json';
        $validation = $this->manifestValidator->validateOfficialFile($manifestPath);

        if (! $validation['valid'] || ! is_array($validation['manifest'])) {
            throw HostPluginInstallException::failed(
                (string) __('dberp.plugin_center.install.manifest_invalid'),
                $validation['error_code'] ?? 'manifest_invalid',
            );
        }

        /** @var array<string, mixed> $manifest */
        $manifest = $validation['manifest'];

        if (! $this->manifestValidator->assertAliasMatchesCode($manifest, $expectedPluginCode)) {
            throw HostPluginInstallException::failed(
                (string) __('dberp.plugin_center.install.alias_mismatch'),
                'manifest_alias_mismatch',
            );
        }

        $alias = trim((string) $manifest['alias']);

        return [
            'manifest' => $manifest,
            'plugin_root' => $pluginRoot,
            'alias' => $alias,
        ];
    }

    public function resolveExtractedPluginRoot(string $stagingDirectory): string
    {
        $manifestAtRoot = $stagingDirectory.DIRECTORY_SEPARATOR.'plugin.json';

        if (is_file($manifestAtRoot)) {
            return $stagingDirectory;
        }

        $children = array_values(array_filter(
            scandir($stagingDirectory) ?: [],
            static fn (string $entry): bool => ! in_array($entry, ['.', '..'], true),
        ));

        foreach ($children as $child) {
            $candidate = $stagingDirectory.DIRECTORY_SEPARATOR.$child;

            if (is_dir($candidate) && is_file($candidate.DIRECTORY_SEPARATOR.'plugin.json')) {
                return $candidate;
            }
        }

        throw HostPluginInstallException::failed(
            (string) __('dberp.plugin_center.install.manifest_invalid'),
            'manifest_missing',
        );
    }
}
