<?php

namespace App\Handlers;

use OSS\OssClient;
require_once '../vendor/aliyuncs/oss-sdk-php/autoload.php';


class AilOss
{
    public static $oss;

    /**
     * @throws \OSS\Core\OssException
     */
    public function __construct()
    {
        $accessKeyId = env('OSS_ACCESS_KEY_ID');                 //获取阿里云oss的accessKeyId
        $accessKeySecret = env('OSS_ACCESS_KEY_SECRET');         //获取阿里云oss的accessKeySecret
        $endpoint = env('OSS_ENDPOINT');                       //获取阿里云oss的endPoint
        self::$oss = new OssClient($accessKeyId, $accessKeySecret, $endpoint);  //实例化OssClient对象
    }

    /**
     *
     * 使用阿里云oss上传文件
     * @param $object   保存到阿里云oss的文件名
     * @param $filepath 文件在本地的绝对路径
     * @return bool     上传是否成功
     * @throws \OSS\Core\OssException
     */
    public function upload($object, $filepath,$bucket ='OSS_BUCKET')
    {
        $res = false;
        $bucket = env($bucket);         //获取阿里云oss的bucket
        if (self::$oss->uploadFile($bucket, $object, $filepath)) {  //调用uploadFile方法把服务器文件上传到阿里云oss
            $res = true;
        }

        return $res;
    }

    /**
     * 删除指定文件
     * @param $object string 被删除的文件名
     * @return bool   删除是否成功
     */
    public function delete(string $object,$bucket = 'OSS_BUCKET')
    {
        $res = false;
        $bucket = env($bucket);
        if (self::$oss->deleteObject($bucket, $object)){ //调用deleteObject方法把服务器文件上传到阿里云oss
            $res = true;
        }

        return $res;
    }

    /**
     * 删除指定文件
     * @param $object 被删除的文件名
     * @return bool   删除是否成功
     */
    public function delete_array($objects,$bucket ='OSS_BUCKET')
    {
        $res = false;
        $bucket = env($bucket);
        if (self::$oss->deleteObjects($bucket, $objects)){ //调用deleteObject方法把服务器文件上传到阿里云oss
            $res = true;
        }

        return $res;
    }


    /*获取文件的临时访问URL*/
    public function getUrl($OssFilePath,$time = 1800,$bucket ='OSS_BUCKET')
    {
        // 生成一个带签名的URL,有效期是3600秒,可以直接使用浏览器访问。
        $timeout = $time;
        $bucket = env($bucket);
        return self::$oss->signUrl($bucket,$OssFilePath,$timeout,"GET");
    }


    /**
     * 在OSS中创建虚拟“文件夹”。名称不应以“/”结尾,因为该方法无论如何都会用“/”追加名称。
     *
     * Internal use only.
     *

     * @param string $dirName 文件夹名称
     * @return bool
     */
    public function createDir($dirName,$bucket = 'OSS_BUCKET')
    {
        $res = false;
        $bucket = env($bucket);
        if (self::$oss->createObjectDir($bucket, $dirName)) {
            $res = true;
        }

        return $res;
    }

    /*获取指定目录下的目录与文件*/
    public function fileList($dir, $maxKey = 1000, $delimiter = '/', $nextMarker = '') {
        $fileList = []; // 获取的文件列表, 数组的一阶表示分页结果
        $dirList = []; // 获取的目录列表, 数组的一阶表示分页结果
        $storageList = [
            'file' => [], // 真正的文件数组
            'dir'  => [], // 真正的目录数组
        ];
        while (true) {
            $options = [
                'delimiter' => $delimiter,
                'prefix'    => $dir,
                'max-keys'  => $maxKey,
                'marker'    => $nextMarker,
            ];
            $bucket =  env('OSS_BUCKET');
            try {
                $fileListInfo = self::$oss->listObjects($bucket, $options);
                // 得到nextMarker, 从上一次 listObjects 读到的最后一个文件的下一个文件开始继续获取文件列表, 类似分页
            } catch (\Exception $e) {
                return  $e->getMessage(); // 发送错误信息
            }
            $nextMarker = $fileListInfo->getNextMarker();
            $fileItem = $fileListInfo->getObjectList();
            $dirItem = $fileListInfo->getPrefixList();
            $fileList[] = $fileItem;
            $dirList[] = $dirItem;
            if ($nextMarker === '') break;
        }
        foreach ($fileList[0] as $item){
            $storageList['file'][] = $this->objectInfoParse($item);
        }
        foreach ($dirList[0] as $item){
            $storageList['dir'][] = $this->prefixInfoParse($item);
        }
        return $storageList; // 发送正确信息
    }

    /* 解析 prefixInfo 类 */
    private function prefixInfoParse($prefixInfo){
        return [
            'dir' => $prefixInfo->getPrefix(),
        ];
    }
    /* 解析 objectInfo 类 */
    public function objectInfoParse($objectInfo) {
        return [
            'name'      => $objectInfo->getKey(),
            'size'      => $objectInfo->getSize(),
            'update_at' => $objectInfo->getLastModified(),
        ];
    }

}