package net.northking.cctp.upperComputer.deviceManager.screen;

import com.alibaba.fastjson.JSON;
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
import net.northking.cctp.upperComputer.entity.Attachment;
import net.northking.cctp.upperComputer.utils.HttpUtils;
import net.northking.cctp.upperComputer.utils.SpringUtils;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author : yineng.huang
 * @date : 2023/10/25 16:30
 */
public class ScreenRecorder {

    private Logger logger = LoggerFactory.getLogger(ScreenRecorder.class);

    private FFmpegFrameRecorder recorder;

    private String filePath;

    private Java2DFrameConverter converter = new Java2DFrameConverter();

    private final int FRAME_RATE = 8;

    private String udid;

    private String videoName;

    private String tenantId;

    private int videoWidth;

    private int videoHeight;

    private String taskId;

    public ScreenRecorder(String udid, String videoName, String tenantId,String taskId, int videoWidth, int videoHeight) {
        this.udid = udid;
        this.videoName = videoName;
        this.tenantId = tenantId;
        this.taskId = taskId;
        this.videoWidth = videoWidth;
        this.videoHeight = videoHeight;
        this.filePath = UpperComputerManager.getInstance().getApplicationPath() + "/screenRecordTmp/";
        File path = new File(filePath);
        if (!path.exists()) {
            path.mkdirs();
        }
        //todo:这里注意改正linux的配置参数，写文件
        recorder = new FFmpegFrameRecorder(filePath + videoName, videoWidth, videoHeight);
//            recorder.setFormat("mp4");
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
//            recorder.setVideoCodec(opencv_cudacodec.MPEG4);
        recorder.setFrameRate(FRAME_RATE);
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
    }

    public void startRecordVideo() {
        try {
            recorder.start();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("录屏启动失败。。。。。。。", e);
        }
        logger.info("设备【{}】已开启录屏.............................",udid);
    }

    public void addImgToVideo(byte[] imgData) {
        try {
            BufferedImage read = ImageIO.read(new ByteArrayInputStream(imgData));
            if (!recorder.isCloseOutputStream()) {
                recorder.record(converter.getFrame(read));
            }
        } catch (IOException e) {
            logger.warn("添加图片文件出现错误。。。。。",e);
        }
    }

    public String endRecord() {
        logger.info("准备结束设备【{}】在taskId:{}的视频录制.............",udid,taskId);
        try {
            recorder.stop();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("结束录屏失败。。。。。。", e);
        }
        try {
            recorder.release();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("释放录屏失败。。。。。。", e);
        }
        String result = uploadVideoToServer();
        logger.info("设备【{}】在taskId:{}的视频录制已经结束，得到的视频地址为：{}.............",udid,taskId,result);
        return result;
    }

    private String uploadVideoToServer() {
        Map<String, String> resultMap = new HashMap<>();
        try {
            //上传文件
            logger.debug("[" +udid+ "]录屏停止，开始上传视屏文件");
            String serverAddress = SpringUtils.getProperties("nk.mobile-computer.serverAddr");
            String pubUploadPath = SpringUtils.getProperties("nk.mobile-computer.publicUploadAddr");
            Attachment upload = HttpUtils.upload(serverAddress + pubUploadPath, filePath + videoName, tenantId);
            if (null != upload && StringUtils.isNotBlank(upload.getId())) {
                logger.debug("文件上传成功，返回id：{}", upload.getId());
                resultMap.put("videoUrl", upload.getUrlPath());
                resultMap.put("videoRef", videoWidth + "x" + videoHeight);
                return JSON.toJSONString(resultMap);
            }
        } catch (Exception e) {
            logger.warn("上传视频文件失败。。。。。。。。", e);
        }finally {

        }
        return null;
    }

    public String getTaskId() {
        return taskId;
    }
}
