package com.yanzuoguang.cloud.file;

import com.yanzuoguang.cloud.vo.req.YzgFileCallbackReqVo;
import com.yanzuoguang.cloud.vo.req.YzgFileCreateReqVo;
import com.yanzuoguang.cloud.vo.req.YzgFileStatusReqVo;
import com.yanzuoguang.mq.service.MqService;
import com.yanzuoguang.mq.vo.MessageVo;
import com.yanzuoguang.mq.vo.QueueVo;
import com.yanzuoguang.util.cache.MemoryCache;
import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.helper.DateHelper;
import com.yanzuoguang.util.helper.JsonHelper;
import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.vo.file.YzgFileMoveReqVo;
import com.yanzuoguang.util.vo.file.YzgFileVideoImageReqVo;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 删除目录
 *
 * @author 颜佐光
 */
@Component
public class YzgFileProcedure implements InitializingBean {

    public static final String YZG_REMOVE_TEMP_FOLDER = "YZG_REMOVE_TEMP_FOLDER";
    public static final String YZG_MOVE_FILE = "YZG_MOVE_FILE";
    public static final String YZG_CONVERT_IMAGE = "YZG_CONVERT_IMAGE";
    public static final String YZG_CONVERT_VIDEO = "YZG_CONVERT_VIDEO";
    public static final String YZG_FILE_CREATE_DELAY = "YZG_FILE_CREATE_DELAY";
    public static final int YZG_FILE_CREATE_DELAY_TIME = 15 * 1000;
    public static final String YZG_FILE_CREATE = "YZG_FILE_CREATE";
    public static final String YZG_FILE_STATUS = "YZG_FILE_STATUS";
    /**
     * 缓存24小时
     */
    private final MemoryCache<Boolean> folderCache = new MemoryCache<>(24 * 60 * 60);
    private final Map<String, Boolean> mapCallbackMQ = new HashMap<>();

    private final MqService mqService;

    public YzgFileProcedure(MqService mqService) {
        this.mqService = mqService;
    }

    @Override
    public void afterPropertiesSet() {
        mqService.createQueue(new QueueVo(YZG_REMOVE_TEMP_FOLDER));
        mqService.createQueue(new QueueVo(YZG_MOVE_FILE));
        mqService.createQueue(new QueueVo(YZG_CONVERT_IMAGE));
        mqService.createQueue(new QueueVo(YZG_CONVERT_VIDEO));
        mqService.createQueue(new QueueVo(YZG_FILE_CREATE_DELAY, YZG_FILE_CREATE_DELAY_TIME, YZG_FILE_CREATE));
        mqService.createQueue(new QueueVo(YZG_FILE_STATUS));
    }

    /**
     * 删除临时文件夹,会自动删除空目录的父文件夹
     *
     * @param serverFolder
     */
    public void removeTempFolder(String serverFolder) {
        synchronized (folderCache) {
            if (StringHelper.toBoolean(folderCache.get(serverFolder))) {
                return;
            }
            folderCache.put(serverFolder, true);
        }
        // 获取当前时间
        Date dt = new Date();
        Date dtTo = DateHelper.addDay(dt, 2);
        String dtToday = DateHelper.getToday(dtTo);
        // 获取延迟时间
        long time = DateHelper.getDateTime(dtToday).getTime() - dt.getTime();
        // 发送删除临时目录的命令
        mqService.message(new MessageVo(YZG_REMOVE_TEMP_FOLDER, serverFolder, time));
    }

    /**
     * 移动文件
     *
     * @param req
     */
    public void moveFile(YzgFileMoveReqVo req) {
        moveFile(JsonHelper.serialize(req), 0);
    }

    /**
     * 移动文件
     *
     * @param json
     * @param dedTime
     */
    public void moveFile(String json, int dedTime) {
        mqService.message(new MessageVo(YZG_MOVE_FILE, json, dedTime));
    }


    /**
     * 转换图片
     *
     * @param req
     */
    public void convertImage(YzgFileVideoImageReqVo req) {
        convertImage(JsonHelper.serialize(req), 0);
    }

    /**
     * 转换图片
     *
     * @param json
     * @param dedTime
     */
    public void convertImage(String json, int dedTime) {
        mqService.message(new MessageVo(YZG_CONVERT_IMAGE, json, dedTime));
    }

    /**
     * 转换视频
     *
     * @param req
     */
    public void convertVideo(YzgFileVideoImageReqVo req) {
        convertVideo(JsonHelper.serialize(req), 0);
    }

    /**
     * 转换视频
     *
     * @param json
     * @param dedTime
     */
    public void convertVideo(String json, int dedTime) {
        mqService.message(new MessageVo(YZG_CONVERT_VIDEO, json, dedTime));
    }

    /**
     * 生成导出文件任务
     *
     * @param req
     */
    public void fileCreate(YzgFileCreateReqVo req) {
        if (StringHelper.isEmpty(req.getFileName())) {
            throw new CodeException("下载文件名不能为空");
        }
        if (StringHelper.isEmpty(req.getCallbackMQ())) {
            throw new CodeException("回调callbackMQ不能为空,请检查后端程序");
        }
        req.init();
        fileCreate(JsonHelper.serialize(req));
    }

    /**
     * 生成导出文件任务
     *
     * @param json
     */
    public void fileCreate(String json) {
        mqService.message(new MessageVo(YZG_FILE_CREATE, json, 0));
    }

    /**
     * 生成导出文件任务,等待15秒后再次调用
     *
     * @param json
     */
    public void fileCreateDelay(String json) {
        mqService.message(new MessageVo(YZG_FILE_CREATE_DELAY, json, 0));
    }

    /**
     * 写入导出文件状态
     *
     * @param req
     */
    public void fileStatus(YzgFileStatusReqVo req) {
        if (StringHelper.isEmpty(req.getFileId(), req.getFileStatus())) {
            return;
        }
        fileStatus(JsonHelper.serialize(req));
    }

    /**
     * 写入导出文件状态
     *
     * @param json
     */
    public void fileStatus(String json) {
        mqService.message(new MessageVo(YZG_FILE_STATUS, json, 0));
    }

    /**
     * 调用回调导出服务任务
     *
     * @param req
     */
    public void fileCallback(YzgFileCallbackReqVo req) {
        if (StringHelper.isEmpty(req.getFileId(), req.getCallbackMQ(), req.getFileServerPath())) {
            return;
        }
        boolean isCreateCallback = mapCallbackMQ.getOrDefault(req.getCallbackMQ(), false);
        if (!isCreateCallback) {
            synchronized (mapCallbackMQ) {
                isCreateCallback = mapCallbackMQ.getOrDefault(req.getCallbackMQ(), false);
                if (!isCreateCallback) {
                    mqService.createQueue(new QueueVo(req.getCallbackMQ()));
                    mapCallbackMQ.put(req.getCallbackMQ(), true);
                }
            }
        }
        String json = JsonHelper.serialize(req);
        mqService.message(new MessageVo(req.getCallbackMQ(), json, 0));
    }
}