package com.sonic.shark.service.impl;

import com.sonic.common.enums.AppEnv;
import com.sonic.shark.enums.ContentTypeEnum;
import com.sonic.shark.enums.S3BizTypeMappingEnum;
import com.sonic.shark.enums.S3BucketNameEnum;
import com.sonic.shark.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.services.s3.model.CopyObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

import java.util.Random;

/**
 * @description: OSS文件上传
 * @author: code
 **/
@Slf4j
@Service
public class OssServiceImpl implements OssService {
    @Autowired
    private S3Client s3Client;

    @Value("${spring.profiles.active}")
    private String runMode;
    /**
     * 测试环境的前缀目录
     */
    private static final String DEV_ENV_PREFIX = "dev/";


    @Override
    public String uploadFileBytes(byte[] bytes, S3BizTypeMappingEnum s3BizTypeMappingEnum, String suffix) {
        //环境参数
        String prefix = AppEnv.product.name().equals(runMode) ? s3BizTypeMappingEnum.getS3BucketNameEnum().getPrefix() : DEV_ENV_PREFIX;
        //根据业务类型拼接出用户的相对路径
        String path = prefix + s3BizTypeMappingEnum.getFilePath();
        Random random = new Random();
        suffix = suffix == null ? "jpg" : suffix;
        String fileName = System.currentTimeMillis() + "" + random.nextInt(10000) + "." + suffix;
        S3BucketNameEnum s3BucketNameEnum = s3BizTypeMappingEnum.getS3BucketNameEnum();
        return uploadByBytes(bytes, s3BucketNameEnum, path, fileName, true);
    }

    @Override
    public String uploadByBytes(byte[] bytes, S3BucketNameEnum s3BucketNameEnum, String path, String fileName, boolean publicRead) {
        try {
            log.info("---------------- START UPLOAD FILE ----------------");
            log.info("uploadByBytes to bucket '" + s3BucketNameEnum.getBucketName());
            String uploadDir = path + fileName;
            PutObjectRequest putObjectRequest;
            if (publicRead) {
                putObjectRequest = PutObjectRequest.builder()
                        .bucket(s3BucketNameEnum.getBucketName())
                        .key(uploadDir)
//                        .acl(CannedAccessControlList.PublicRead.toString())
                        .contentType(getContentType(fileName.substring(fileName.lastIndexOf("."))))
                        .cacheControl("no-cache")
                        .build();
            } else {
                putObjectRequest = PutObjectRequest.builder()
                        .bucket(s3BucketNameEnum.getBucketName())
                        .key(uploadDir)
//                        .acl(CannedAccessControlList.Private.toString())
                        .contentType(getContentType(fileName.substring(fileName.lastIndexOf("."))))
                        .cacheControl("no-cache")
                        .build();
            }
            PutObjectResponse putObjectResponse = s3Client.putObject(
                    putObjectRequest,
                    RequestBody.fromBytes(bytes));
            log.info("uploadByBytes putObjectResponse : {}", putObjectResponse);
            log.info("===================== Upload File - Done! =====================");
            return s3BucketNameEnum.getRootUrl() + uploadDir;
        } catch (Exception e) {
            log.info("Exception e:" + e.toString());
        }
        return null;
    }

    @Override
    public String copyFile(S3BucketNameEnum sourceS3BucketNameEnum, String sourceFilePath, S3BucketNameEnum targetS3BucketNameEnum, String targetFilePath) {
        try {
            Long startTime = System.currentTimeMillis();
            CopyObjectRequest copyRequest = CopyObjectRequest.builder()
                    .copySource(sourceS3BucketNameEnum.getBucketName() + "/" + sourceFilePath)
                    .destinationBucket(targetS3BucketNameEnum.getBucketName())
                    .destinationKey(targetFilePath)
                    .build();
            CopyObjectResponse copyResponse = s3Client.copyObject(copyRequest);
            log.info("===> copyFile status : {} ", copyResponse.copyObjectResult().eTag());
            log.info("===> time : {} ms", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            //复制失败，打印日志
            log.error("===> copyFile error : ", e);
        }
        return targetFilePath;
    }

    /**
     * 获取文件类型
     *
     * @param fileSuffix
     * @return
     */
    public static String getContentType(String fileSuffix) {
        String result = ContentTypeEnum.getContentType(fileSuffix);
        return result == null ? "application/octet-stream" : result;
    }

}
