package com.fdkanfang.common.util;

import com.aliyun.oss.*;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;

/**
 * @author abnerhou
 * @date 2020/5/28 10:37
 * @desciption
 */
@Service
@Slf4j
public class OssCheckPointUploadUtil {

    @Value("${oss.point}")
    private String endpoint;

    @Value("${oss.key}")
    private String accessKeyId;

    @Value("${oss.secrey}")
    private String accessKeySecret;

    @Value("${oss.bucket}")
    private String bucketName;

    public void doUploadThenDelete(String uploadFile, String objectName) {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            File localFile = new File(uploadFile);
            log.info("Object name = {}", objectName);
            UploadFileRequest uploadFileRequest = new UploadFileRequest(bucketName, objectName);
            // The local file to upload---it must exist.
            // 指定上传的本地文件。
            uploadFileRequest.setUploadFile(uploadFile);
            log.info("本地文件为:{}", uploadFile);
            // Sets the concurrent upload task number to 5.
            uploadFileRequest.setTaskNum(5);
            // Sets the part size to 1MB.
            uploadFileRequest.setPartSize(1024 * 1024 * 1);
            // 开启断点续传，默认关闭。
            // Enables the checkpoint file. By default it's off.
            uploadFileRequest.setEnableCheckpoint(true);
            // 记录本地分片上传结果的文件。开启断点续传功能时需要设置此参数，上传过程中的进度信息会保存在该文件中，如果某一分片上传失败，再次上传时会根据文件中记录的点继续上传。上传完成后，该文件会被删除。默认与待上传的本地文件同目录，为uploadFile.ucp。
            String localCheckFile = localFile.getName() + "_uploadFile.ucp";
            uploadFileRequest.setCheckpointFile(localCheckFile);

            UploadFileResult uploadResult = ossClient.uploadFile(uploadFileRequest);

            CompleteMultipartUploadResult multipartUploadResult =
                    uploadResult.getMultipartUploadResult();
            log.info("断点续传结果:{}", multipartUploadResult.getETag());

        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message: " + oe.getErrorMessage());
            System.out.println("Error Code:       " + oe.getErrorCode());
            System.out.println("Request ID:      " + oe.getRequestId());
            System.out.println("Host ID:           " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ce.getMessage());
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            ossClient.shutdown();
            FileUtils.deleteFile(uploadFile);
            log.info("关闭oss client，并且本地删除文件");
        }
    }

    public void upload2(String filePath, String key1) {
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                log.error("要上传的文件不存在：" + filePath);
                return;
            }
            ossClient.putObject(bucketName, key1, file);
        } catch (Exception e) {
            log.error(e.toString() + filePath);
        }
    }

    public String downloadFileFromOss(String localFilePath, String newFileName,
                                      String bucketName, String objectKey) throws IOException {
        if (StringUtils.isNoneBlank(localFilePath, bucketName, objectKey)) {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

/*            OSS ossClient = new OSSClientBuilder().build("http://oss-cn-shenzhen.aliyuncs.com"
                    , "LTAIUrvuHqj8pvry", "JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4");*/

            // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
            OSSObject ossObject = ossClient.getObject(new GetObjectRequest(bucketName, objectKey));
            String fileName = "";
            if (StringUtils.isNotBlank(newFileName)) {
                fileName = newFileName;
            } else {
                int index = objectKey.lastIndexOf("/");
                if (index != -1) {
                    fileName = objectKey.substring(index + 1, objectKey.length());
                }
            }

            File directory = new File(localFilePath);
            if (!directory.exists()) {
                directory.mkdirs();
            }
            localFilePath += fileName;
            if (null != ossObject) {
                File file = new File(localFilePath);
                if (file.exists()) {
                    FileUtils.deleteFile(localFilePath);
                    file = new File(localFilePath);
                }
                InputStream inputStream = ossObject.getObjectContent();
                if (null == inputStream) {
                    log.error("获取oss返回的输入流失败");
                    return localFilePath;
                }
                BufferedInputStream inputBuff = new BufferedInputStream(inputStream);
                // 输出缓冲流
                BufferedOutputStream stream = null;
                try {
                    stream = new BufferedOutputStream(new FileOutputStream(file));
                    int len = 0;
                    byte[] buffer = new byte[1024];
                    while ((len = inputBuff.read(buffer)) != -1) {
                        stream.write(buffer, 0, len);
                    }
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (null != stream) {
                        stream.flush();
                        stream.close();
                        inputBuff.close();
                    }
                }

            }
            // 关闭OSSClient。
            ossClient.shutdown();
        } else {
            log.error("入参为空，无法下载oss的照片");
        }
        return localFilePath;
    }

    public  String downLoadOssFileWithSdk(String localDirectory, String newFileName,
                                       String bucketName, String objectKey) {
        if (StringUtils.isNoneBlank(localDirectory, bucketName, objectKey)) {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
         /*   OSS ossClient = new OSSClientBuilder().build("http://oss-cn-shenzhen.aliyuncs.com"
                    , "LTAIUrvuHqj8pvry", "JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4");*/
            String fileName = "";
            if (StringUtils.isNotBlank(newFileName)) {
                fileName = newFileName;
            } else {
                int index = objectKey.lastIndexOf("/");
                if (index != -1) {
                    fileName = objectKey.substring(index + 1, objectKey.length());
                }
            }
            File directory = new File(localDirectory);
            if (!directory.exists()) {
                //递归生成目录
                directory.mkdirs();
            }
            String localFilePath = localDirectory + fileName;
            File totalFile = new File(localFilePath);
            // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
            ossClient.getObject(new GetObjectRequest(bucketName, objectKey), totalFile);
            // 关闭OSSClient。
            ossClient.shutdown();
            return localFilePath;
        }
        return localDirectory;
    }


/*        public static void main(String[] args){

            System.out.println(downLoadOssFileWithSdk("E:\\data\\fdkanfang\\abner\\test\\",
                    "mytest.jpg" , "4dkankan","images/images0EkILn1TL/pan/high/31.jpg"));
            System.out.println("done==");
        }*/


    }
