package com.ruoyi.common.utils.oss;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * 阿里云OSS工具类
 * 
 * @author ruoyi
 */
public class OssUtils
{
    private static final Logger log = LoggerFactory.getLogger(OssUtils.class);

    /**
     * 生成OSS上传签名
     * 
     * @param endpoint OSS endpoint
     * @param accessKeyId AccessKey ID
     * @param accessKeySecret AccessKey Secret
     * @param bucket Bucket名称
     * @param dir 上传目录，例如 "dept/logo/"
     * @param expireTime 过期时间（秒），默认1小时
     * @return 签名信息
     */
    public static Map<String, String> generatePostPolicy(String endpoint, String accessKeyId, 
            String accessKeySecret, String bucket, String dir, long expireTime)
    {
        try
        {
            if (expireTime <= 0)
            {
                expireTime = 3600; // 默认1小时
            }

            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); // 最大1GB
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            // 使用OSS Client生成PostPolicy
            OSS ossClient = new OSSClientBuilder().build("https://" + endpoint, accessKeyId, accessKeySecret);
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);
            
            ossClient.shutdown();

            Map<String, String> respMap = new LinkedHashMap<>();
            respMap.put("accessKeyId", accessKeyId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", "https://" + bucket + "." + endpoint);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));

            return respMap;
        }
        catch (Exception e)
        {
            log.error("生成OSS签名失败", e);
            return null;
        }
    }

    /**
     * 生成文件路径
     * 
     * @param originalFilename 原始文件名
     * @param dir 目录前缀
     * @return 文件路径
     */
    public static String generateFilePath(String originalFilename, String dir)
    {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        
        String ext = "";
        if (originalFilename != null && originalFilename.contains("."))
        {
            ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        
        String timestamp = String.valueOf(System.currentTimeMillis());
        String random = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
        
        return dir + year + "/" + String.format("%02d", month) + "/" + String.format("%02d", day) + "/" + timestamp + "_" + random + ext;
    }
}

