
package com.artfess.file.util;

import com.obs.services.ObsConfiguration;
import com.obs.services.model.AuthTypeEnum;
import com.obs.services.model.PutObjectRequest;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.GetObjectRequest;
import com.obs.services.model.HeaderResponse;
import com.obs.services.model.HttpMethodEnum;
import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.ObsObject;
import com.obs.services.model.ProgressListener;
import com.obs.services.model.ProgressStatus;
import com.obs.services.model.PutObjectResult;
import com.obs.services.model.TemporarySignatureRequest;
import com.obs.services.model.TemporarySignatureResponse;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@Slf4j
@Component
public class HuaweiyunOssUtil {

    private static String ak;
    private static String sk;

    private static String bucketName;
    private static String endpoint;

    public static String getAk() {
        return ak;
    }

    public static void setAk(String ak) {
        HuaweiyunOssUtil.ak = ak;
    }

    public static String getSk() {
        return sk;
    }

    public static void setSk(String sk) {
        HuaweiyunOssUtil.sk = sk;
    }

    public static String getBucketName() {
        return bucketName;
    }

    public static void setBucketName(String bucketName) {
        HuaweiyunOssUtil.bucketName = bucketName;
    }

    public static String getEndpoint() {
        return endpoint;
    }

    public static void setEndpoint(String endpoint) {
        HuaweiyunOssUtil.endpoint = endpoint;
    }

    private static ObsClient obsClient = null;

    /**
     * 上传文件
     * path:文件路径
     *
     * @return
     */
    public static String uploadFile(String path) {
        try {
            initObsClient(ak, sk, endpoint);
            File file = new File(path);
            FileInputStream fis = new FileInputStream(file);
            PutObjectResult response = obsClient.putObject(bucketName, file.getName(), fis);
            // 可选：调用成功后，记录调用成功的HTTP状态码和服务端请求ID
            int statusCode = response.getStatusCode();
            //obsClient.close();
            if (200 == statusCode) {
                return response.getObjectUrl();
            }

        } catch (IOException e) {
            log.error("文件上传失败：{}", e.getMessage(), e);
        }
        return "";
    }

    // 上传文件
    public static String uploadFile(MultipartFile file, String filePath) {
        try {
            initObsClient(ak, sk, endpoint);
            PutObjectRequest request = new PutObjectRequest(bucketName, filePath, file.getInputStream());
            PutObjectResult response = obsClient.putObject(request);
            int statusCode = response.getStatusCode();
            //obsClient.close();
            if (200 == statusCode) {
                return response.getObjectUrl();
            }
        }catch (IOException e) {
            log.error("文件上传失败：{}", e.getMessage(), e);
        }
        return "";

    }

    /**
     * 上传文件--流式
     *
     * @param fileName 上传文件名称
     * @param is       文件流
     * @return
     */
    public static String uploadFile(String fileName, InputStream is) {
        try {
            initObsClient(ak, sk, endpoint);
            PutObjectResult response = obsClient.putObject(bucketName, fileName, is);
            // 可选：调用成功后，记录调用成功的HTTP状态码和服务端请求ID
            int statusCode = response.getStatusCode();
            is.close();
            //obsClient.close();
            if (200 == statusCode) {
                return response.getObjectUrl();
            }

        } catch (ObsException e) {
            System.out.println("HTTP Code: " + e.getResponseCode());
            System.out.println("Error Code:" + e.getErrorCode());
            System.out.println("Request ID:" + e.getErrorRequestId());
            // 推荐：发生异常后，记录异常堆栈信息
            e.printStackTrace(System.out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }



    /**
     * @param fileName：文件名称
     * @Description: 下载
     * @Return: byte[]
     * @Author: llj
     * @Date: 2021/3/19 16:07
     */
    public static byte[] Download(String fileName, OutputStream out) throws IOException {

        initObsClient(ak, sk, endpoint);
        ObsObject obsObject = obsClient.getObject(bucketName, fileName);
        // 读取对象内容
        InputStream input = obsObject.getObjectContent();
        byte[] b = new byte[1024];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len;
        while ((len = input.read(b)) != -1) {
            out.write(b, 0, len);
        }
        out.close();
        input.close();
       // obsClient.close();
        return bos.toByteArray();
    }

    public void downloadFile(String objectKey, HttpServletResponse response) throws IOException {
        initObsClient(ak, sk, endpoint);
        ObsObject obsObject = obsClient.getObject(bucketName, objectKey);
        try (InputStream input = obsObject.getObjectContent();
             OutputStream output = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = input.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
            output.flush();
        }
    }
    /*
     * @Description:
     * @param [fileName]
     * @Return: void
     * @Author: llj
     * @Date: 2021/3/19 16:08
     */
    public static void DownloadChange(String fileName) throws IOException {
        // 创建ObsClient实例
        initObsClient(ak, sk, endpoint);
        GetObjectRequest request = new GetObjectRequest(bucketName, fileName);
        request.setProgressListener(new ProgressListener() {

            @Override
            public void progressChanged(ProgressStatus status) {
                // 获取下载平均速率
                System.out.println("AverageSpeed:" + status.getAverageSpeed());
                // 获取下载进度百分比
                System.out.println("TransferPercentage:" + status.getTransferPercentage());
            }
        });
        // 每上传1MB数据反馈下载进度
        request.setProgressInterval(1024 * 1024L);
        ObsObject obsObject = obsClient.getObject(request);

        // 读取对象内容
        System.out.println(obsObject.toString());
        InputStream input = obsObject.getObjectContent();
        byte[] b = new byte[1024];
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len;
        while ((len = input.read(b)) != -1) {
            bos.write(b, 0, len);
        }
        System.out.println(new String(bos.toByteArray()));
        bos.close();
        input.close();
    }

    /**
     * 获取文件下载地址
     *
     * @param fileName 文件名称
     * @return
     */
    public static String getDownloadUrl(String fileName) {
        initObsClient(ak, sk, endpoint);
        // URL有效期，3600秒.5分钟
        long expireSeconds = 3600L;
        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
        request.setBucketName(bucketName);
        request.setObjectKey(fileName);
        TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
        return response.getSignedUrl();
    }

    public static boolean chekckFile(String fileName) {
        initObsClient(ak, sk, endpoint);
        ObjectMetadata metadata = obsClient.getObjectMetadata(bucketName, fileName);
        if (metadata == null) {
            return false;
        }
        return true;

    }

    /**
     * @param fileName obs上桶下文件路径
     * @Description: 删除附件
     * @Return: boolean
     * @Author: llj
     * @Date: 2021/3/23 10:08
     */
    public static boolean deleteFile(String fileName) {
        try {
            initObsClient(ak, sk, endpoint);
            obsClient.deleteObject(bucketName, fileName);
           // obsClient.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 初始化客户端
     *
     * @param ak
     * @param sk
     * @param endpoint
     * @return
     */
    private static ObsClient initObsClient(String ak, String sk, String endpoint) {
        if (obsClient == null) {
            ObsConfiguration config = new ObsConfiguration();
            config.setSocketTimeout(30000);
            config.setConnectionTimeout(10000);
            config.setEndPoint(endpoint);
          //  config.setAuthType(AuthTypeEnum.OBS);
            obsClient = new ObsClient(ak, sk, config);
        }
        return obsClient;
    }
}

