<?php
namespace  App\Lib\Ccwl\Oss;

use OSS\OssClient;
use OSS\Core\OssException;

class AliyunOssDriver implements IOssDriver
{
    private $oss_access_id = '';
    private $oss_access_key = '';
    private $oss_endpoint = '';
    private $oss_bucket = '';

    private $errors = [];

    private $ossClient = null;

    /**
     * 橙橙网络封装OSS client
     * 
     * @param string $oss_access_id
     * @param string $oss_access_key
     * @param string $oss_endpoint
     * @param string $oss_bucket
     * 
     * @return null
     */
    public function __construct($config)
    {
        $this->oss_access_id = $config['oss_access_id'];
        $this->oss_access_key = $config['oss_access_key'];
        $this->oss_endpoint = $config['oss_endpoint'];
        $this->oss_bucket = $config['oss_bucket'];

        $this->ossClient = $this->getOssClient();
    }

    protected function getOssClient()
    {
        try {
            $ossClient = new OssClient($this->oss_access_id, $this->oss_access_key, $this->oss_endpoint, false);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception  CREATE instance: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return null;
        }
        return $ossClient;
    }


    /**
     * 写入文件对象
     * 
     * @param string $object OSS上最终的 文件路径+文件名
     * @param string $content 对象内容
     * @param array $options 参数选项， 默认为空
     * 
     * @return mixed bool|array
     */
    public function putObject($object, $content, $options=[])
    {
        try {
            $result = $this->ossClient->putObject($this->oss_bucket, $object, $content, $options);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception method: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return false;
        }
        return $result;
    }


    /**
     * 上传文件对象
     * 
     * @param string $object OSS上最终的 文件路径+文件名
     * @param string $filePath 待上传的本地文件路径
     * @param array $options 参数选项， 默认为空
     * 
     * @return mixed bool|array
     */
    public function uploadFile($object, $filePath, $options=[])
    {
        try {
            $result = $this->ossClient->uploadFile($this->oss_bucket, $object, $filePath, $options);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception method: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return false;
        }
        return $result;
    }


    /**
     * 判断对象是否存在
     * 
     * @param string $object OSS上最终的 文件路径+文件名
     * 
     * @return mixed bool|int
     */
    public function doesObjectExist($object)
    {
        try {
            $exist = $this->ossClient->doesObjectExist($this->oss_bucket, $object);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception method: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return false;
        }
        return $exist;
    }


    /**
     * 删除对象
     * 
     * @param string $object OSS上最终的 文件路径+文件名
     * 
     * @return mixed bool|array
     */
    public function deleteObject($object)
    {
        try {
            $result = $this->ossClient->deleteObject($this->oss_bucket, $object);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception method: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return false;
        }
        return $result;
    }

    /**
     * 获取对象上传的签名URL
     * 
     * @param string $object OSS上最终的 文件路径+文件名
     * @param array $options  文件类型
     * 
     * @return mixed bool|string
     */
    public function getSignedUrl($object, $options=['Content-Type'=>'image/jpeg'])
    {
        $timeout = 3600;
        try {
            $signedUrl = $this->ossClient->signUrl($this->oss_bucket, $object, $timeout, "PUT", $options);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception method: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return false;
        }
        return $signedUrl;
    }

    /**
     * 获取错误信息
     * 
     * @return string 错误信息
     */
    public function getError() {
        return implode(PHP_EOL, $this->errors);
    }

    private function errorLog($message)
    {
        $this->errors[] = $message;
        // print($message);
        error_log($message);    
    }

    public function listObjects($prefix="/")
    {     
        $delimiter = '/';
        $nextMarker = '';
        $maxkeys = 1000;
        $options = array(
            'delimiter' => $delimiter,
            'prefix' => $prefix,
            'max-keys' => $maxkeys,
            'marker' => $nextMarker,
        );
        try {
            $listObjectInfo = $this->ossClient->listObjects($this->oss_bucket, $options);
        } catch (OssException $e) {
            $this->errorLog("CccwlOssClinet exception method: ". __FUNCTION__ . ", error: " . $e->getMessage() . PHP_EOL);
            return;
        }
       
        $objectList = $listObjectInfo->getObjectList(); // object list
        $prefixList = $listObjectInfo->getPrefixList(); // directory list
        if (!empty($objectList)) {
            print("objectList:\n");
            foreach ($objectList as $objectInfo) {
                print($objectInfo->getKey() . "\n");
            }
        }
        if (!empty($prefixList)) {
            print("prefixList: \n");
            foreach ($prefixList as $prefixInfo) {
                print($prefixInfo->getPrefix() . "\n");
            }
        }
    }
}
