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

use Core\service\BaseCoreService;


/**
 * 升级备份服务
 * @package app\service\domain\upgrade
 */
class UpgradeBackupService extends BaseCoreService
{
    /**
     * 备份文件
     * @param array $fileList 文件列表
     * @param string $version 版本号
     * @return string 备份目录
     */
    public function backup(array $fileList, string $version): string
    {
        $backupDir = $this->backupDir($version);
        $timestamp = date('YmdHis');
        $backupDir = rtrim($backupDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $timestamp;

        if (!is_dir($backupDir)) {
            mkdir($backupDir, 0755, true);
        }

        $siteRoot = dirname($this->app->getRootPath()) . DIRECTORY_SEPARATOR;
        foreach ($fileList as $file) {
            $source = $siteRoot . ltrim($file, DIRECTORY_SEPARATOR);
            if (!file_exists($source)) {
                continue;
            }

            $relative = ltrim(str_replace('\\', '/', $file), '/');
            $target = $backupDir . DIRECTORY_SEPARATOR . $relative;
            $targetParent = dirname($target);
            if (!is_dir($targetParent)) {
                mkdir($targetParent, 0755, true);
            }

            copy($source, $target);
        }

        return $backupDir;
    }


    /**
     * 恢复备份
     * @param string $backupPath 备份目录
     * @return bool 是否恢复成功
     */
    public function restore(string $backupPath): bool
    {
        if (!is_dir($backupPath)) {
            return false;
        }

        $rootPath = dirname($this->app->getRootPath()) . DIRECTORY_SEPARATOR;
        $this->copyDir($backupPath, $rootPath);

        return true;
    }

    /**
     * 复制目录
     * @param string $src 源目录
     * @param string $dst 目标目录
     */
    private function copyDir(string $src, string $dst): void
    {
        $dir = opendir($src);
        if (!$dir) {
            return;
        }

        while (($file = readdir($dir)) !== false) {
            if ($file === '.' || $file === '..') {
                continue;
            }
            $srcFile = $src . DIRECTORY_SEPARATOR . $file;
            $dstFile = $dst . DIRECTORY_SEPARATOR . $file;

            if (is_dir($srcFile)) {
                if (!is_dir($dstFile)) {
                    mkdir($dstFile, 0755, true);
                }
                $this->copyDir($srcFile, $dstFile);
            } else {
                $dstParent = dirname($dstFile);
                if (!is_dir($dstParent)) {
                    mkdir($dstParent, 0755, true);
                }
                copy($srcFile, $dstFile);
            }
        }
        closedir($dir);
    }

    /**
     * 获取备份目录
     * @param string $version 版本号
     * @return string 备份目录
     */
    private function backupDir(string $version): string
    {

        return $this->app->getRootPath() . 'data' . DIRECTORY_SEPARATOR . 'upgrade' . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . $version;
    }
}