<?php
// +----------------------------------------------------------------------
// | saiadmin [ saiadmin快速开发框架 ]
// +----------------------------------------------------------------------
// | Author: sai <1430792918@qq.com>
// +----------------------------------------------------------------------
namespace plugin\saiadmin\service\storage;

use plugin\saiadmin\app\logic\system\SystemConfigLogic;
use plugin\saiadmin\exception\ApiException;
use plugin\saiadmin\utils\Arr;

/**
 * 文件上传服务
 * @method static array uploadFile(array $config = [])  上传文件
 * @method static array uploadBase64(string $base64, string $extension = 'png') 上传Base64文件
 * @method static array uploadServerFile(string $file_path)  上传服务端文件
 */
class UploadService
{
    /**
     * @desc 存储磁盘
     * @param int $type
     * @param string $upload
     * @param bool $_is_file_upload
     * @return mixed
     */
    public static function disk(int $type = 1, string $upload = 'image', bool $_is_file_upload = true)
    {
        $logic = new SystemConfigLogic();
        $uploadConfig = $logic->getGroup('upload_config');

        $file = current(request()->file());
        $ext = $file->getUploadExtension() ?: null;
        $file_size = $file->getSize();
        if ($file_size > Arr::getConfigValue($uploadConfig, 'upload_size')) {
            throw new ApiException('File size exceeds limit');
        }
        $allow_file = Arr::getConfigValue($uploadConfig, 'upload_allow_file');
        $allow_image = Arr::getConfigValue($uploadConfig, 'upload_allow_image');
        if ($upload == 'image') {
            if (!in_array($ext, explode(',', $allow_image))) {
                throw new ApiException('File format not supported for upload');
            }
        } else {
            if (!in_array($ext, explode(',', $allow_file))) {
                throw new ApiException('File format not supported for upload');
            }
        }
        switch ($type) {
            case 1:
                // 本地
                $config = [
                    'adapter' => \Tinywan\Storage\Adapter\LocalAdapter::class,
                    'root' => Arr::getConfigValue($uploadConfig, 'local_root'),
                    'dirname' => function () {
                        return date('Ymd');
                    },
                    'domain' => Arr::getConfigValue($uploadConfig, 'local_domain'),
                    'uri' => Arr::getConfigValue($uploadConfig, 'local_uri'),
                    'algo' => 'sha1',
                ];
                break;
            case 2:
                // 阿里云
                $config = [
                    'adapter' => \Tinywan\Storage\Adapter\OssAdapter::class,
                    'accessKeyId' => Arr::getConfigValue($uploadConfig, 'oss_accessKeyId'),
                    'accessKeySecret' => Arr::getConfigValue($uploadConfig, 'oss_accessKeySecret'),
                    'bucket' => Arr::getConfigValue($uploadConfig, 'oss_bucket'),
                    'dirname' => Arr::getConfigValue($uploadConfig, 'oss_dirname'),
                    'domain' => Arr::getConfigValue($uploadConfig, 'oss_domain'),
                    'endpoint' => Arr::getConfigValue($uploadConfig, 'oss_endpoint'),
                    'algo' => 'sha1',
                ];
                break;
            case 3:
                // 七牛
                $config = [
                    'adapter' => \Tinywan\Storage\Adapter\QiniuAdapter::class,
                    'accessKey' => Arr::getConfigValue($uploadConfig, 'qiniu_accessKey'),
                    'secretKey' => Arr::getConfigValue($uploadConfig, 'qiniu_secretKey'),
                    'bucket' => Arr::getConfigValue($uploadConfig, 'qiniu_bucket'),
                    'dirname' => Arr::getConfigValue($uploadConfig, 'qiniu_dirname'),
                    'domain' => Arr::getConfigValue($uploadConfig, 'qiniu_domain'),
                ];
                break;
            case 4:
                // 腾讯云
                $config = [
                    'adapter' => \Tinywan\Storage\Adapter\CosAdapter::class,
                    'secretId' => Arr::getConfigValue($uploadConfig, 'cos_secretId'),
                    'secretKey' => Arr::getConfigValue($uploadConfig, 'cos_secretKey'),
                    'bucket' => Arr::getConfigValue($uploadConfig, 'cos_bucket'),
                    'dirname' => Arr::getConfigValue($uploadConfig, 'cos_dirname'),
                    'domain' => Arr::getConfigValue($uploadConfig, 'cos_domain'),
                    'region' => Arr::getConfigValue($uploadConfig, 'cos_region'),
                ];
                break;
            case 5:
                // s3 亚马逊
                $config = [
                    'adapter' => \Tinywan\Storage\Adapter\S3Adapter::class,
                    'key' => Arr::getConfigValue($uploadConfig, 's3_key'),
                    'secret' => Arr::getConfigValue($uploadConfig, 's3_secret'),
                    'bucket' => Arr::getConfigValue($uploadConfig, 's3_bucket'),
                    'dirname' => Arr::getConfigValue($uploadConfig, 's3_dirname'),
                    'domain' => Arr::getConfigValue($uploadConfig, 's3_domain'),
                    'region' => Arr::getConfigValue($uploadConfig, 's3_region'),
                    'version' => Arr::getConfigValue($uploadConfig, 's3_version'),
                    // 'use_path_style_endpoint' => Arr::getConfigValue($uploadConfig,'s3_use_path_style_endpoint'),
                    'use_path_style_endpoint' => filter_var(Arr::getConfigValue($uploadConfig, 's3_use_path_style_endpoint'), FILTER_VALIDATE_BOOLEAN),
                    'endpoint' => Arr::getConfigValue($uploadConfig, 's3_endpoint'),
                    'acl' => Arr::getConfigValue($uploadConfig, 's3_acl'),
                ];
                break;
            default:
                throw new ApiException('Upload mode not found');
        }
        return new $config['adapter'](array_merge(
            $config,
            ['_is_file_upload' => $_is_file_upload]
        ));
    }

    /**
     * @param $name
     * @param $arguments
     * @return mixed
     * @author Tinywan(ShaoBo Wan)
     */
    public static function __callStatic($name, $arguments)
    {
        return static::disk()->{$name}(...$arguments);
    }
}
