<?php

declare(strict_types=1);

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

namespace App\Services\SupportCenter;

/**
 * 生成建议在服务器终端 / SSH / 面板终端执行的系统更新命令。
 */
final class HostSystemUpdateCliCommandBuilder
{
    public function __construct(
        private readonly PhpCliBinaryResolver $phpCliBinaryResolver,
    ) {}

    /**
     * @return array{cd_command: string, run_command: string, combined: string, project_path: string, uses_detected_php: bool, cli_php_substituted_from_cgi: bool}
     */
    public function buildTerminalScript(string $executionNo): array
    {
        $executionNo = trim($executionNo);
        $projectPath = base_path();
        $cdCommand = $this->buildChangeDirectoryCommand();
        $runCommand = $this->buildRunCommand($executionNo);
        $phpBinary = $this->resolveSuggestedPhpBinary();

        return [
            'cd_command' => $cdCommand,
            'run_command' => $runCommand,
            'combined' => $cdCommand.PHP_EOL.$runCommand,
            'project_path' => $projectPath,
            'uses_detected_php' => $phpBinary !== null,
            // 对照原始 PHP_BINARY，勿用已规范化的 resolution.path（cgi 已被替换为 php）。
            'cli_php_substituted_from_cgi' => $this->phpCliBinaryResolver
                ->isSuggestedBinarySubstitutedFromCgi(suggestedBinary: $phpBinary),
        ];
    }

    public function buildChangeDirectoryCommand(): string
    {
        return 'cd '.$this->shellQuote(base_path());
    }

    public function buildRunCommand(?string $executionNo = null): string
    {
        $executionNo = trim((string) $executionNo);

        if ($executionNo === '') {
            return $this->artisanInvocation().' dberp:system-update:run';
        }

        return $this->artisanInvocation().' dberp:system-update:run '.$this->shellQuote($executionNo);
    }

    /**
     * @return array{cd_command: string, run_command: string, combined: string, project_path: string, uses_detected_php: bool, cli_php_substituted_from_cgi: bool}
     */
    public function buildFullTerminalScript(): array
    {
        return $this->buildTerminalScript('');
    }

    public function resolveSuggestedPhpBinary(): ?string
    {
        return $this->phpCliBinaryResolver->resolveSuggestedBinary();
    }

    private function artisanInvocation(): string
    {
        $phpBinary = $this->resolveSuggestedPhpBinary();

        if ($phpBinary !== null) {
            if (PHP_OS_FAMILY === 'Windows') {
                return '& '.$this->shellQuote($phpBinary).' artisan';
            }

            return $this->shellQuote($phpBinary).' artisan';
        }

        return 'php artisan';
    }

    private function shellQuote(string $value): string
    {
        if (PHP_OS_FAMILY === 'Windows') {
            return '"'.str_replace('"', '\"', $value).'"';
        }

        return escapeshellarg($value);
    }
}
