package cn.meowrain.aioj.backend.fileservice.service;

import cn.hutool.crypto.digest.DigestUtil;
import cn.meowrain.aioj.backend.fileservice.config.FileConfigurationProperties;
import cn.meowrain.aioj.backend.fileservice.dao.entity.AttachmentDO;
import cn.meowrain.aioj.backend.fileservice.dao.mapper.AttachmentMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 异步哈希计算服务
 *
 * @author meowrain
 * @since 2026-01-10
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class HashCalculationService {

    private final AttachmentMapper attachmentMapper;
    private final FileConfigurationProperties fileConfigurationProperties;

    /**
     * 异步计算大文件哈希（只计算，不删除文件）
     *
     * @param attachmentId 新上传的附件ID
     * @param storagePath  存储路径
     * @param storageType  存储类型
     */
    @Async("fileExecutor")
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void calculateHashAsync(Long attachmentId, String storagePath, String storageType) {
        FileInputStream fis = null;
        try {
            log.info("开始异步计算大文件哈希: attachmentId={}, storagePath={}, storageType={}",
                    attachmentId, storagePath, storageType);

            String fileHash;
            if ("LOCAL".equals(storageType)) {
                String fullPath = fileConfigurationProperties.getLocal().getBasePath() + "/" + storagePath;
                File file = new File(fullPath);
                fis = new FileInputStream(file);
                fileHash = DigestUtil.sha256Hex(fis);
            } else {
                log.warn("暂不支持云存储的异步哈希计算: storageType={}", storageType);
                return;
            }

            // 只更新哈希值，不删除文件
            AttachmentDO update = new AttachmentDO();
            update.setId(attachmentId);
            update.setFileHash(fileHash);
            attachmentMapper.updateById(update);

            log.info("大文件哈希计算完成: attachmentId={}, fileHash={}", attachmentId, fileHash);

        } catch (IOException e) {
            log.error("异步计算大文件哈希失败: attachmentId={}", attachmentId, e);
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    log.error("关闭文件流失败", e);
                }
            }
        }
    }
}
