package com.yanzuoguang.media;

import com.yanzuoguang.util.MediaHelper;
import com.yanzuoguang.util.exception.CodeException;
import com.yanzuoguang.util.helper.FileHelper;
import com.yanzuoguang.util.helper.JsonHelper;
import com.yanzuoguang.util.thread.ThreadHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * 直播首页操作
 *
 * @author 颜佐光
 */
@Component
public class MediaFirst {

    /**
     * 判断该视频是否已经实现处理
     */
    @Autowired(required = false)
    private MediaCache cache;

    private MediaCacheBase cacheLocal = new MediaCacheLocal();

    public MediaFirst() {

    }

    private MediaCacheBase getCache() {
        if (cache != null) {
            return cache;
        }
        return cacheLocal;
    }

    public MediaFirst(MediaCache cache) {
        this.cache = cache;
    }

    public MediaResVo start(MediaReqVo req) {
        // 将临时文件移动到正式文件
        this.getCache().lockTempFile(req, new Runnable() {
            @Override
            public void run() {
                File file = getFile(req);
                File fileTemp = getFileTemp(req);
                FileHelper.createDirectory(file.getParentFile());
                if (fileTemp.exists()) {
                    fileTemp.renameTo(file);
                }
            }
        });

        // 通过判断,当没有开启线程运行时,则开启线程运行
        return this.getCache().start(req, new Runnable() {
            @Override
            public void run() {
                // 开始开启线程运行
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        handle(req);
                    }
                });
                thread.start();
            }
        });
    }

    private File getFile(MediaReqVo req) {
        return new File(req.getImageUrl());
    }

    private File getFileTemp(MediaReqVo req) {
        return new File(req.getImageUrl() + ".tmp");
    }

    private File getDownM3muFile(MediaReqVo req) {
        return new File(req.getImageUrl() + ".tmp.mp4");
    }

    private File getCatTempFile(MediaReqVo req) {
        return new File(req.getImageUrl() + ".tmp.jpg");
    }

    private void handle(MediaReqVo req) {
        do {
            MediaResVo res = this.getCache().get(req);
            if (res == null) {
                res = JsonHelper.to(req, MediaResVo.class);
            }
            try {
                // 下载m3mu并转换成mp4
                downM3mu(req);
                // 转换为图片
                catImage(req);
                // 将下载临时文件移动到临时文件
                this.getCache().lockTempFile(req, new Runnable() {
                    @Override
                    public void run() {
                        File mp4 = getDownM3muFile(req);
                        File catTemp = getCatTempFile(req);
                        File fileTemp = getFileTemp(req);
                        if (catTemp.exists()) {
                            catTemp.renameTo(fileTemp);
                        }
                        mp4.delete();
                    }
                });
                // 写入缓存
                this.getCache().sub(res);
                // 判断是否还有执行次数
                if (isFinish(req)) {
                    break;
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            ThreadHelper.sleep(res.getSplit());
        } while (!isFinish(req));

    }

    private void downM3mu(MediaReqVo req) throws Exception {
        String localUrl = getDownM3muFile(req).getAbsolutePath();
        HlsDownloader downloader = new HlsDownloader(req.getUrl(),
                localUrl,
                1,
                1
        );
        downloader.download(false, true);
    }

    private void catImage(MediaReqVo req) {
        String localTempUrl = this.getDownM3muFile(req).getAbsolutePath();
        String localCatUrl = this.getCatTempFile(req).getAbsolutePath();
        MediaHelper.getVideoFirstImage(localTempUrl, localCatUrl);
    }

    public boolean isFinish(MediaReqVo req) {
        MediaResVo res = this.getCache().get(req);
        System.out.println("剩余次数:" + res.getCount());
        // 判断是否还有执行次数
        return res.getCount() < 1;
    }
}