package cn.reghao.oss.store.task;

import cn.reghao.oss.store.db.repository.ImageRepository;
import cn.reghao.oss.store.model.vo.ObjectResult;
import cn.reghao.oss.store.task.processor.AudioFileProcessor;
import cn.reghao.oss.store.task.processor.DiskFileProcessor;
import cn.reghao.oss.store.task.processor.ImageFileProcessor;
import cn.reghao.oss.store.task.processor.VideoFileProcessor;
import cn.reghao.jutil.jdk.thread.ThreadPoolWrapper;
import cn.reghao.oss.api.constant.ObjectType;
import cn.reghao.oss.api.constant.UploadChannel;
import cn.reghao.oss.api.rest.UploadFileRet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutorService;

/**
 * @author reghao
 * @date 2023-05-22 18:11:03
 */
@Slf4j
@Service
public class FileProcessor {
    private final ExecutorService threadPool = ThreadPoolWrapper.threadPool("file-processor", 10);
    private final ImageFileProcessor imageFileProcessor;
    private final VideoFileProcessor videoFileProcessor;
    private final AudioFileProcessor audioFileProcessor;
    private final DiskFileProcessor diskFileProcessor;
    private final ImageRepository imageRepository;

    public FileProcessor(ImageFileProcessor imageFileProcessor, VideoFileProcessor videoFileProcessor,
                         AudioFileProcessor audioFileProcessor, DiskFileProcessor diskFileProcessor,
                         ImageRepository imageRepository) {
        this.imageFileProcessor = imageFileProcessor;
        this.videoFileProcessor = videoFileProcessor;
        this.audioFileProcessor = audioFileProcessor;
        this.diskFileProcessor = diskFileProcessor;
        this.imageRepository = imageRepository;
    }

    public UploadFileRet process(ObjectResult objectResult, int channelId) throws Exception {
        String objectName = objectResult.getObjectName();
        int fileType = objectResult.getFileType();
        ObjectType objectType = ObjectType.getByCode(fileType);
        UploadFileRet uploadFileRet = null;

        UploadChannel channel = UploadChannel.getUploadChannel(channelId);
        switch (channel) {
            case disk:
                uploadFileRet = diskFileProcessor.process(objectResult);
                //uploadFileRet = processFile(objectResult, channelId);
                break;
            case video:
                uploadFileRet = videoFileProcessor.process(objectResult);
                break;
            case audio:
                uploadFileRet = audioFileProcessor.process(objectResult);
                break;
            case avatar:
            case image:
            case img:
                uploadFileRet = imageFileProcessor.processImage(objectResult, channelId);
                setUrl(channelId, uploadFileRet);
                break;
            case photo:
                uploadFileRet = imageFileProcessor.processImage(objectResult, channelId);
                break;
            default:
                log.info("{} 类型的 {} 文件暂时无法处理", objectType.name(), objectName);
        }
        return uploadFileRet;
    }

    private void setUrl(int channelId, UploadFileRet uploadFileRet) {
        String uploadId = uploadFileRet.getUploadId();
        String url = imageRepository.getImageUrl(channelId, uploadId).getOriginalUrl();
        uploadFileRet.setUrl(url);
    }

    private UploadFileRet processFile(ObjectResult objectResult, int channelId) throws Exception {
        int fileType = objectResult.getFileType();
        UploadFileRet uploadFileRet;
        if (fileType == ObjectType.Image.getCode()) {
            uploadFileRet = imageFileProcessor.processImage(objectResult, channelId);
        } else if (fileType == ObjectType.Video.getCode()) {
            uploadFileRet = videoFileProcessor.process(objectResult);
        } else if (fileType == ObjectType.Audio.getCode()) {
            uploadFileRet = audioFileProcessor.process(objectResult);
        } else if (fileType == ObjectType.Text.getCode()) {
            uploadFileRet = diskFileProcessor.process(objectResult);
        } else {
            uploadFileRet = diskFileProcessor.process(objectResult);
        }

        return uploadFileRet;
    }
}
