package com.hzs.common.core.utils;

import com.hzs.common.core.config.AwsConfig;
import com.hzs.common.core.utils.uuid.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.auth.credentials.*;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

import java.io.File;

/**
 * @Description: AWS 使用工具
 * @Author: jiang chao
 * @Time: 2023/11/3 14:49
 * @Classname: AwsUtil
 * @PackageName: com.hzs.common.core.utils
 */
@Slf4j
public class AwsUtil {

    /**
     * 上传 MultipartFile
     *
     * @param file     MultipartFile
     * @param path     文件路径
     * @param fileName 文件名称
     * @return
     */
    public static String uploadMultipartFile(final MultipartFile file, final String path, final String fileName) {
        try {
            // 文件路径
            String key = createKey(file, path, fileName);

            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(AwsConfig.getBucketName())
                    .key(key)
                    .build();
            PutObjectResponse putObjectResponse = createClient().putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));
            log.info("文件上传成功：{}", putObjectResponse.eTag());

            return key;
        } catch (Exception e) {
            log.error("上传文件失败", e);
        }
        return null;
    }

    /**
     * 上传 MultipartFile
     *
     * @param file MultipartFile
     * @return
     */
    public static String uploadMultipartFile(final MultipartFile file) {
        try {
            // 文件路径
            String key = createKey(file, null, null);

            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(AwsConfig.getBucketName())
                    .key(key)
                    .build();
            PutObjectResponse putObjectResponse = createClient().putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));
            log.info("文件上传成功：{}", putObjectResponse.eTag());

            return key;
        } catch (Exception e) {
            log.error("上传文件失败", e);
        }
        return null;
    }

    /**
     * 上传 File
     *
     * @param file     File
     * @param path     文件路径
     * @param fileName 文件名称
     * @return
     */
    public static String uploadFile(final File file, final String path, final String fileName) {
        try {
            String key = AwsConfig.getPrefixDirectory() + "/";
            // 存储路径
            if (StringUtils.isNotEmpty(path)) {
                key += path;
            } else {
                key += DateUtils.parseDateToStr(DateUtils.YAMMER);
            }
            key += "/";
            // 文件名称
            if (StringUtils.isNotEmpty(fileName)) {
                key += fileName;
            } else {
                key += UUID.fastUUID() + "." + UploadUtils.getFileExtension(file);
            }

            PutObjectRequest putObjectRequest = PutObjectRequest.builder()
                    .bucket(AwsConfig.getBucketName())
                    .key(key)
                    .build();
            PutObjectResponse putObjectResponse = createClient().putObject(putObjectRequest, RequestBody.fromFile(file));
            log.info("文件上传成功：{}", putObjectResponse.eTag());

            return key;
        } catch (Exception e) {
            log.error("上传文件失败", e);
        }
        return null;
    }

    /**
     * 创建文件key（上传路径 + 文件名）
     *
     * @param file     上传的文件
     * @param path     路径 - 可为空
     * @param fileName 文件名
     * @return
     */
    private static String createKey(MultipartFile file, String path, String fileName) {
        String key = AwsConfig.getPrefixDirectory() + "/";
        // 存储路径
        if (StringUtils.isNotEmpty(path)) {
            key += path;
        } else {
            key += DateUtils.parseDateToStr(DateUtils.YAMMER);
        }
        key += "/";
        // 文件名称
        if (StringUtils.isNotEmpty(fileName)) {
            key += fileName;
        } else {
            key += UUID.fastUUID() + "." + UploadUtils.getFileExtension(file);
        }
        return key;
    }

    /**
     * 创建 S3Client
     *
     * @return
     */
    private static S3Client createClient() {
        return S3Client.builder()
                .region(Region.of(AwsConfig.getRegion()))
                .credentialsProvider(getAwsCredentialsProviderChain())
                .build();
    }

    /**
     * 获取aws供应商凭据
     *
     * @return
     */
    private static AwsCredentialsProviderChain getAwsCredentialsProviderChain() {
        return AwsCredentialsProviderChain
                .builder()
                .addCredentialsProvider(() -> AwsBasicCredentials.create(AwsConfig.getAccessKey(), AwsConfig.getSecretKey()))
                .build();
    }

}
