package com.keyware.shandan.mark.services;

import cn.hutool.core.collection.ConcurrentHashSet;
import com.keyware.shandan.bianmu.entity.DirectoryVo;
import com.keyware.shandan.bianmu.service.DirectoryService;
import com.keyware.shandan.common.constants.DirConstant;
import com.keyware.shandan.mark.config.MarkFileBuilder;
import com.keyware.shandan.mark.config.MarkFileCache;
import com.keyware.shandan.mark.pojo.MarkFile;
import com.keyware.shandan.mark.pojo.MarkRecord;
import com.keyware.shandan.system.entity.SysFile;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;


/**
 * 文件自动置标服务类
 *
 * @author GuoXin
 * @date 2022-07-26
 */
@Slf4j
@Service
public class FileAutoMarkService {
    private final ConcurrentHashSet<SysFile> files = new ConcurrentHashSet<>();
    @Autowired
    private MarkFileCache markFileCache;
    @Autowired
    private MarkFileBuilder markFileBuilder;
    @Autowired
    private MarkRecordService markRecordService;
    @Autowired
    private DirectoryService directoryService;

    public void addFile(SysFile file, Long operateId) {
        if (isMarkFile(file)) {
            markFileCache.put(file.getEntityId() + operateId, markFileBuilder.build(file));
            log.debug("》》》》发现置标文件");
        } else {
            files.add(file);
        }
    }

    public void startMark(Long operateId) {
        log.debug("》》》开始置标");
        try {
            files.forEach(file -> {
                // 先进行目录级别置标
                markingByDirectory(file, operateId);
                // 再进行文件级别置标
                markingByFile(file, operateId);
                // 保存置标记录
                //markRecordService.saveOrUpdateBatch(file.getMarkRecords());
            });
        } finally {
            clear();
        }
    }

    private void markingByDirectory(SysFile file, Long operateId) {
        MarkFile markFile = findMarkFile(file.getEntityId(), operateId);
        if (markFile != null) {
            fillRecords(file, markFile.getMarkConfig().get("默认置标"));
        } else {
            log.error("》》》没有找到默认置标数据{}", file.getFileName());
        }
    }

    private void markingByFile(SysFile file, Long operateId) {
        String fileName = file.getFileName().replace(file.getFileSuffix(), "");
        MarkFile markFile = markFileCache.get(file.getEntityId() + operateId);
        if (markFile != null) {
            fillRecords(file, markFile.getMarkConfig().get(fileName));
        } else {
            log.error("》》》没有找到单个文件置标数据{}", file.getFileName());
        }
    }

    /**
     * 查找置标文件，如果当前目录下没有，则查找父级目录
     *
     * @param directoryId 目录ID
     * @return MarkFile
     */
    private MarkFile findMarkFile(String directoryId, Long operateId) {
        MarkFile markFile = markFileCache.get(directoryId + operateId);
        if (markFile == null) {
            DirectoryVo directory = directoryService.getById(directoryId);
            if (!DirConstant.DIR_ROOT_ID.equals(directory.getParentId())) {
                markFile = findMarkFile(directory.getParentId(), operateId);
            }
        }
        return markFile;
    }

    private void fillRecords(SysFile file, List<MarkRecord> recordList) {
        if (recordList != null) {
            recordList.forEach(record -> {
                record.setEntityId(file.getId());
                record.setId(record.md5());
            });
            //file.setMarkRecords(recordList);
        }
    }

    /**
     * 通过文件名称判断文件是否为置标文件
     *
     * @param file 文件
     * @return boolean
     */
    private boolean isMarkFile(SysFile file) {
        return "置标文件.text".equalsIgnoreCase(file.getFileName())
                || "置标文件.txt".equalsIgnoreCase(file.getFileName())
                || "置标文件".equalsIgnoreCase(file.getFileName());
    }

    private void clear() {
        markFileCache.clear();
        files.clear();
    }
}
