package cd.casic.ci.process.process.service.aflManager.impl;

import cd.casic.ci.process.process.dao.aflManager.AflFileChunkDao;
import cd.casic.ci.process.process.dataObject.aflManager.AflFileChunk;
import cd.casic.ci.process.process.service.aflManager.AflFileChunkService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import de.danielbechler.util.Collections;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

/**
 * @author HopeLi
 * @version v1.0
 * @ClassName TargetVersionServiceImpl
 * @Date: 2025/5/17 15:20
 * @Description:
 */
@Service
@Slf4j
public class AflFileChunkServiceImpl extends ServiceImpl<AflFileChunkDao, AflFileChunk> implements AflFileChunkService {
    @Resource
    private AflFileChunkDao aflFileChunkDao;

    // 每个分片大小为 2GB
    private static final Long CHUNK_SIZE = 1024 * 1024 * 1024 * 2L;

    @Override
    public byte[] getFileById(String contentId) throws IOException {
        QueryWrapper<AflFileChunk> wrapper = new QueryWrapper<>();
        wrapper.eq("content_id", contentId);
        List<AflFileChunk> chunks = aflFileChunkDao.selectList(wrapper);
        if (chunks == null || chunks.isEmpty()) {
            return new byte[0];
        }

        int totalLength = chunks.stream()
                .mapToInt(chunk -> chunk.getChunkContent() != null ? chunk.getChunkContent().length : 0)
                .sum();

        byte[] result = new byte[totalLength];
        int position = 0;

        for (AflFileChunk chunk : chunks) {
            byte[] data = chunk.getChunkContent();
            if (data != null) {
                System.arraycopy(data, 0, result, position, data.length);
                position += data.length;
            }
        }
        return result;
    }

    @Override
    public String saveFileChunk(InputStream file) {
        if (file == null) {
            return null;
        }

        String contentId = UUID.randomUUID().toString();

        try {
            byte[] buffer = new byte[CHUNK_SIZE.intValue()];
            int bytesRead;
            int chunkIndex = 0;

            // 第一次遍历：读取所有分片并保存
            while ((bytesRead = file.read(buffer)) != -1) {
                byte[] chunkData = new byte[bytesRead]; // 实际读取的大小
                System.arraycopy(buffer, 0, chunkData, 0, bytesRead);

                AflFileChunk chunk = new AflFileChunk();
                chunk.setContentId(contentId);
                chunk.setChunkIndex(chunkIndex++);
                chunk.setChunkContent(chunkData);

                this.baseMapper.insert(chunk);
            }

            // 第二次遍历：更新每个分片的总分片数
            QueryWrapper<AflFileChunk> wrapper = new QueryWrapper<>();
            wrapper.eq("content_id", contentId);
            List<AflFileChunk> aflFileChunks = baseMapper.selectList(wrapper);
            if (!Collections.isEmpty(aflFileChunks)){
                aflFileChunks.forEach(o->{
                    o.setChunksSum(aflFileChunks.size());
                });
            }
            baseMapper.updateBatch(aflFileChunks);

        } catch (IOException e) {
            log.error("文件分片上传失败", e);
            throw new RuntimeException("文件上传失败");
        }

        return contentId;
    }
}
