package com.ruoyi.common.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.utils.uuid.UUID;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.Objects;

@Configuration
@Slf4j
public class OssUtils {

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

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

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

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

    @SneakyThrows
    public String upload(File file) {
        String originalFileName = file.getName();
        String fileName = String.format("%s%s", IdUtils.fastSimpleUUID(), originalFileName.substring(originalFileName.lastIndexOf(".")));
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String url;
        try (InputStream inputStream = new FileInputStream(file)) {
            ossClient.putObject(bucketName, fileName, inputStream);
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, fileName);
            request.setExpiration(DateUtils.addYears(new Date(), 3));
            url = ossClient.generatePresignedUrl(request).toString();
            log.info("文件上传url = {}", url);
        } finally {
            if (Objects.nonNull(ossClient)) {
                ossClient.shutdown();
            }
        }
        return url;
    }

    public String upload(MultipartFile file) throws IOException {

        String originalFileName = file.getOriginalFilename();
        String fileName = UUID.randomUUID() + originalFileName.substring(originalFileName.lastIndexOf("."));
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String url = new String();
        Date no = new Date();
        no.setYear(no.getYear() + 3);
        try (InputStream inputStream = file.getInputStream()) {
            ossClient.putObject(bucketName, fileName, inputStream);
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, fileName);
            request.setExpiration(no);
            url = ossClient.generatePresignedUrl(request).toString();
            log.info("文件上传 ,url = " + url);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return url;
    }

    public int deleteFile(String url) throws IOException {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        URL url1 = new URL(url);
        try {
            ossClient.deleteObject(bucketName, url1.getPath().split("/")[1]);
            log.info("文件刪除 ,url = " + url);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return 1;
    }

    public InputStream getInputStreamByUrl(String url) {
        return getInputStreamByName(getFileNameByUrl(url));
    }

    public String getFileNameByUrl(String url) {
        int start = url.lastIndexOf("/") + 1;
        int end = url.lastIndexOf("?");
        return end > 0 ? url.substring(start, end) : url.substring(start);
    }

    @SneakyThrows
    public InputStream getInputStreamByName(String fileName) {
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            return IOUtils.toBufferedInputStream(ossClient.getObject(bucketName, fileName).getObjectContent());
        } finally {
            ossClient.shutdown();
        }
    }
}
