package com.chushang.inspection.ins;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ZipUtil;
import com.chushang.common.core.constant.SecurityConstants;
import com.chushang.common.core.web.Result;
import com.chushang.inspection.work.vo.InspectionConfigVO;
import com.chushang.inspection.work.vo.WrkInfoDetailsVO;
import com.chushang.oss.config.UploadConfig;
import com.chushang.oss.entity.dto.UploadBytesDTO;
import com.chushang.oss.entity.vo.FileSourceVo;
import com.chushang.oss.feign.RemoteOssService;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 模板生成工厂
 * @auther: zhao
 * @date: 2024/7/1 9:33
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GeneratedInsFactory {
    private final TemplateService templateService;
    private final RemoteOssService remoteOssService;
    private static final ExecutorService EXECUTOR = ThreadUtil.newExecutor(
            Runtime.getRuntime().availableProcessors() * 2,
            Runtime.getRuntime().availableProcessors() * 4,
            Integer.MAX_VALUE);
    private final Map<String, GeneratedIns> generatedInsMap;
    public String getPath() {
        return UploadConfig.getTmpPath() + File.separator + "download" + File.separator + "word" + File.separator;
    }
    public String generated(Map<Long, WrkInfoDetailsVO> wrkMaps){
        // 生成文件路径
        String basePath = getPath();
        AtomicReference<String> url = new AtomicReference<>(null);
        // 只能使用这种方式 -- 因为不确定需要生成的具体模板数量
        List<CompletableFuture<Void>> supplyAsync = Lists.newCopyOnWriteArrayList();
        // 此处 进行 压缩文件夹
        // 此处应当指定 需要生成的 路径
        wrkMaps.forEach((wrkId, wrk)->{
            // 生成普通巡检单
            GeneratedIns defaultGeneratedIns = generatedInsMap.get("default");
            // 生成默认的 word
            // 为null 时, 取默认 default 模板
            supplyAsync.addAll(defaultGeneratedIns.generated(wrkMaps, null, getPath(), remoteOssService,templateService,EXECUTOR));
            List<InspectionConfigVO> inspections = wrk.getInspections();
            inspections.forEach(ins->{
                // 别名
                String alias = ins.getAlias();
                // 模板
                GeneratedIns generatedIns = generatedInsMap.get(alias);
                supplyAsync.addAll(generatedIns.generated(wrkMaps, ins, basePath,remoteOssService,templateService,EXECUTOR));
            });
        });
        // 等待所有线程执行完成
        CompletableFuture.allOf(supplyAsync.toArray(new CompletableFuture[0])).join();
        log.info("所有线程 执行完毕");
        if (FileUtil.exist(basePath)) {
            File zip = ZipUtil.zip(basePath);
            try {
                // 上传文件到oss 中
                Result<List<FileSourceVo>> listResult = remoteOssService.uploadBytes(UploadBytesDTO.builder()
                                .bytes(FileUtil.readBytes(zip))
                                .build(),
                        null,
                        false,
                        "",
                        "downFile", SecurityConstants.INNER);
                // 不为空时, 说明 上传成功
                if (listResult.isSuccess() && CollectionUtil.isNotEmpty(listResult.getData())){
                    log.info("上传成功");
                    url.set(listResult.getData().get(0).getFilePath());
                }
            }finally {
                FileUtil.del(zip);
                FileUtil.del(new File(basePath).getParent());
            }
        }
        log.info("准备返回 {}" , url.get());
        return url.get();
    }

}
