<?php



class FileRemote
{
    protected $config;
    protected $basePath;
    protected $buctkets_ali = [];
// bucket所属地域：华北 'tj' 华东 'sh' 华南 'gz' 北京 'bj'
    // 西南 'cd' 新加坡 'sgp' 香港 'hk' 多伦多 'ca' 法兰克福 'ger'
    public static function init($config = [], $basePath = SITE_PATH)
    {
        $fileRemote = new FileRemote($config, $basePath);
        return $fileRemote;
    }

    public function __construct($config = [], $basePath = SITE_PATH)
    {
        $this->config = $config;
        $this->basePath = $basePath;
        $this->basePath = rtrim($this->basePath, "/") . "/";
    }

    public function upload($filename, $auto_delete_local = true, $is_split_upload = false)
    {
        $config = $this->config;
        $rs = ['code' => 0, 'msg' => ''];
        if (empty($config['type'])) {
            $rs['msg'] = '未配置远程附件';
            return $rs;
        }
        $filename = ltrim($filename, "/");
        if ($config['type'] == '1') {
            $ftp_config = array(
                'hostname' => $config['ftp']['host'],
                'username' => $config['ftp']['username'],
                'password' => $config['ftp']['password'],
                'port' => $config['ftp']['port'],
                'ssl' => $config['ftp']['ssl'],
                'passive' => $config['ftp']['pasv'],
                'timeout' => $config['ftp']['timeout'],
                'rootdir' => $config['ftp']['dir'],
            );
            $ftp = new \ftp\Ftp($ftp_config);
            if (true === $ftp->connect()) {
                $response = $ftp->upload($this->basePath . '/' . $filename, $filename);
                if ($response === true) {
                    $rs['code'] = 1;
                    $rs['url'] = $config['ftp']['url'] . "/" . $filename;
                } else {
                    $rs['msg'] = '远程附件上传失败，请检查配置并重新上传';
                }
            } else {
                $rs['msg'] = '远程附件上传失败，请检查配置并重新上传';
            }
        } elseif ($config['type'] == '2') {
            $buckets = $this->alioss_buctkets($config['alioss']['key'], $config['alioss']['secret']);
            $host_name = $config['alioss']['internal'] ? '-internal.aliyuncs.com' : '.aliyuncs.com';
            $endpoint = 'http://' . $buckets[$config['alioss']['bucket']]['location'] . $host_name;
            try {
                $ossClient = new \OSS\OssClient($config['alioss']['key'], $config['alioss']['secret'], $endpoint);
                if ($is_split_upload) {
                    $options = ['partSize' => 1048576]; // 分片大小为1M
                    $ossClient->multiuploadFile($config['alioss']['bucket'], $filename, $this->basePath . $filename, $options);
                } else {
                    $ossClient->uploadFile($config['alioss']['bucket'], $filename, $this->basePath . $filename);
                }
                $rs['code'] = 1;
                $rs['url'] = $config['alioss']['url'] . "/" . $filename;
            } catch (\OSS\Core\OssException $e) {
                $rs['msg'] = $e->getMessage();
            }
        } elseif ($config['type'] == '3') {
            $auth = new Qiniu\Auth($config['qiniu']['accesskey'], $config['qiniu']['secretkey']);
            $qn_config = new Qiniu\Config();
            $uploadmgr = new Qiniu\Storage\UploadManager($qn_config);
            $putpolicy = Qiniu\base64_urlSafeEncode(json_encode(array(
                'scope' => $config['qiniu']['bucket'] . ':' . $filename,
            )));
            $uploadtoken = $auth->uploadToken($config['qiniu']['bucket'], $filename, 3600, $putpolicy);
            list($ret, $err) = $uploadmgr->putFile($uploadtoken, $filename, $this->basePath . '/' . $filename);
            if ($err !== null) {
                $rs['msg'] = '远程附件上传失败，请检查配置并重新上传';
            } else {
                $rs['code'] = 1;
                $rs['url'] = $config['qiniu']['url'] . "/" . $filename;
            }
        } elseif ($config['type'] == '4') {
            try {
                $cosClient = new \QCloud\Cos\Client(
                    array(
                        'region' => $config['cos']['local'],
                        'credentials' => array(
                            'secretId' => $config['cos']['secretid'],
                            'secretKey' => $config['cos']['secretkey'])));
                $cosClient->Upload($config['cos']['bucket'] . '-' . $config['cos']['appid'], $filename, fopen($this->basePath . '/' . $filename, 'rb'));
            } catch (\Exception $e) {
                $rs['msg'] = $e->getMessage();
                return $rs;
            }
            $rs['code'] = 1;
            $rs['url'] = $config['cos']['url'] . "/" . $filename;
        }
        elseif ($config['type'] == '5') {
            $endpoint = 'http://obs.'.$config['huaweioss']['local'] .'.myhuaweicloud.com';
            $key =$config['huaweioss']['key'];
            $secret =$config['huaweioss']['secret'];
            try {
                $ossClient = new \HuaweiCloud\OssClient($key,$secret, $endpoint);
                $ossClient->uploadFile($config['huaweioss']['bucket'], $filename,  '');
                $rs['code'] = 1;
                $rs['url'] = $config['alioss']['url'] . "/" . $filename;
            } catch (\OSS\Core\OssException $e) {
                $rs['msg'] = $e->getMessage();
            }
        }
        if ($auto_delete_local) {
            $this->file_delete($filename);
        }
        return $rs;
    }

    function file_delete($file)
    {
        if (empty($file)) {
            return false;
        }
        if (file_exists($file)) {
            @unlink($file);
        }
        if (file_exists($this->basePath . '/' . $file)) {
            @unlink($this->basePath . '/' . $file);
        }
        return true;
    }

    function file_remote_delete($file)
    {
        if (empty($file)) {
            return true;
        }
        $rs = ['code' => 0, 'msg' => ''];
        $config = $this->config;
        if ($config['type'] == '1') {
            $ftp_config = array(
                'hostname' => $config['ftp']['host'],
                'username' => $config['ftp']['username'],
                'password' => $config['ftp']['password'],
                'port' => $config['ftp']['port'],
                'ssl' => $config['ftp']['ssl'],
                'passive' => $config['ftp']['pasv'],
                'timeout' => $config['ftp']['timeout'],
                'rootdir' => $config['ftp']['dir'],
            );
            $ftp = new \ftp\Ftp($ftp_config);
            if (true === $ftp->connect()) {
                if ($ftp->delete_file($file)) {
                    return true;
                } else {
                    $rs['msg'] = '删除附件失败，请检查配置并重新删除';
                    return $rs;
                }
            } else {
                $rs['msg'] = '删除附件失败，请检查配置并重新删除';
                return $rs;
            }
        } elseif ($config['type'] == '2') {
            $buckets = $this->alioss_buctkets($config['alioss']['key'], $config['alioss']['secret']);
            $endpoint = 'http://' . $buckets[$config['alioss']['bucket']]['location'] . '.aliyuncs.com';
            try {
                $ossClient = new \OSS\OssClient($config['alioss']['key'], $config['alioss']['secret'], $endpoint);
                $ossClient->deleteObject($config['alioss']['bucket'], $file);
            } catch (\OSS\Core\OssException $e) {
                $rs['msg'] = '删除oss远程文件失败';
                return $rs;
            }
        } elseif ($config['type'] == '3') {
            $auth = new Qiniu\Auth($config['qiniu']['accesskey'], $config['qiniu']['secretkey']);
            $bucketMgr = new Qiniu\Storage\BucketManager($auth);
            $error = $bucketMgr->delete($config['qiniu']['bucket'], $file);
            if ($error instanceof Qiniu\Http\Error) {
                if ($error->code() == 612) {
                    return true;
                }
                $rs['msg'] = '删除七牛远程文件失败';
                return $rs;
            } else {
                return true;
            }
        } elseif ($config['type'] == '4') {
            $key = '/' . $file;
            $bucket = $config['cos']['bucket']."-".$config['cos']['appid'];
            try {
                $cosClient = new \QCloud\Cos\Client(
                    array(
                        'region' => $config['cos']['local'],
                        'credentials' => array(
                            'secretId' => $config['cos']['secretid'],
                            'secretKey' => $config['cos']['secretkey'])));

                /*$cosClient->deleteObjects(array(
                    'Bucket' => $config['cos']['bucket'],
                    'Objects' => array(array('Key' => $key))
                ));*/
                $cosClient->deleteObject(array(
                    //bucket的命名规则为{name}-{appid} ，此处填写的存储桶名称必须为此格式
                    'Bucket' => $bucket,
                    'Key' => $key ));
            } catch (\Exception $e) {
                $rs['msg'] = $e->getMessage();
                return $rs;
            }
        }
        return true;
    }

    public function qiniu_auth($key, $secret, $bucket, $file)
    {
        $auth = new Qiniu\Auth($key, $secret);
        $token = $auth->uploadToken($bucket);
        $config = new Qiniu\Config();
        $uploadmgr = new Qiniu\Storage\UploadManager($config);
        list($ret, $err) = $uploadmgr->putFile($token, 'test.png', $file);
        if ($err !== null) {
            $err = (array)$err;
            $err = (array)array_pop($err);
            $err = json_decode($err['body'], true);
            return ['code' => -1, 'msg' => $err];
        } else {
            return true;
        }
    }

    public function cos_auth($bucket, $appid, $key, $secret, $bucket_local, $file)
    {
        $rs = ['code' => -1, 'msg' => ''];
        if (!is_numeric($appid)) {
            $rs['msg'] = '传入appid值不合法, 请重新输入';
            return $rs;
        }
        if (!preg_match('/^[a-zA-Z0-9]{36}$/', $key)) {
            $rs['msg'] = '传入secretid值不合法, 请重新输入';
            return $rs;
        }
        if (!preg_match('/^[a-zA-Z0-9]{32}$/', $secret)) {
            $rs['msg'] = '传入secretkey值不合法, 请重新输入';
            return $rs;
        }
        try {
            $cosClient = new \QCloud\Cos\Client(
                array(
                    'region' => $bucket_local,
                    'credentials' => array(
                        'secretId' => $key,
                        'secretKey' => $secret)));
            $cosClient->Upload($bucket . '-' . $appid, 'test.png', fopen($file, 'rb'));
        } catch (\Exception $e) {
            $rs['msg'] = $e->getMessage();
            return $rs;
        }
        return true;
    }

    public static function alioss_datacenters()
    {
        $bucket_datacenter = array(
            'oss-cn-hangzhou' => '杭州数据中心',
            'oss-cn-qingdao' => '青岛数据中心',
            'oss-cn-beijing' => '北京数据中心',
            'oss-cn-hongkong' => '香港数据中心',
            'oss-cn-shenzhen' => '深圳数据中心',
            'oss-cn-shanghai' => '上海数据中心',
            'oss-us-west-1' => '美国硅谷数据中心',
        );
        return $bucket_datacenter;
    }

    public function alioss_buctkets($key, $secret)
    {
        $url = 'http://oss-cn-beijing.aliyuncs.com';
        try {
            $ossClient = new \OSS\OssClient($key, $secret, $url);
        } catch (\OSS\Core\OssException $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        try {
            $bucketlistinfo = $ossClient->listBuckets();
        } catch (OSS\OSS_Exception $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        $bucketlistinfo = $bucketlistinfo->getBucketList();
        $bucketlist = array();
        foreach ($bucketlistinfo as &$bucket) {
            $bucketlist[$bucket->getName()] = array('name' => $bucket->getName(), 'location' => $bucket->getLocation());
        }
        $this->buctkets_ali = $bucketlist;
        return $bucketlist;
    }

    public function alioss_auth($key, $secret, $bucket, $internal = false, $file)
    {
        $buckets = empty($this->buctkets_ali) ? $this->alioss_buctkets($key, $secret) : $this->buctkets_ali;
        $host = $internal ? '-internal.aliyuncs.com' : '.aliyuncs.com';
        $url = 'http://' . $buckets[$bucket]['location'] . $host;
        try {
            $ossClient = new \OSS\OssClient($key, $secret, $url);
            $ossClient->uploadFile($bucket, 'test.png', $file);
        } catch (\OSS\Core\OssException $e) {
            return ['code' => 0, 'msg' => $e->getMessage()];
        }
        return true;
    }

}
