package net.northking.cctp.upperComputer.webSocket.thread;

import com.alibaba.fastjson.JSON;
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
import net.northking.cctp.upperComputer.enums.FileBusinessTypeEnum;
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 IosScreenRecordThread extends Thread{

    private Logger logger = LoggerFactory.getLogger(IosScreenRecordThread.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 currentTaskId;

    public IosScreenRecordThread(String udid, String videoName, String tenantId, int videoWidth, int videoHeight, String currentTaskId) {
        this.udid = udid;
        this.videoName = videoName;
        this.tenantId = tenantId;
        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.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setFrameRate(FRAME_RATE);
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        this.currentTaskId = currentTaskId;
    }

    @Override
    public void run() {
        try {
            recorder.start();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("录屏启动失败。。。。。。。", e);
        }
        while (!isInterrupted()) {
            logger.info("ios设备【{}】录屏中。。。。。。。。。。。。。", udid);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                break;
            }
        }
        logger.info("结束ios设备【{}】任务【{}】的录屏。。。。。。。", udid, videoName);
    }

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

    public String endRecord() {
        try {
            recorder.stop();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("结束录屏失败。。。。。。", e);
        }
        try {
            recorder.release();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("释放录屏失败。。。。。。", e);
        }
        String result = uploadVideoToServer();
        this.interrupt();
        return result;
    }

    public String endRecord(Boolean save) {
        try {
            recorder.stop();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("结束录屏失败。。。。。。", e);
        }
        try {
            recorder.release();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("释放录屏失败。。。。。。", e);
        }
        String result = null;
        if (null != save && save) {
            result = uploadVideoToServer();
        }else {
            logger.debug("录屏文件不保存！");
        }
        this.interrupt();
        return result;
    }

    public String endRecord(String tenantId,Boolean save) {
        this.tenantId = tenantId;
        return endRecord(save);
    }


    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");
            logger.info("开始上传ios视频文件");
            Attachment upload = HttpUtils.upload(serverAddress + pubUploadPath, filePath + videoName, tenantId, currentTaskId, FileBusinessTypeEnum.MOBILE_TASK_VIDEO.getCode());
            if (null != upload && StringUtils.isNotBlank(upload.getId())) {
                logger.info("文件上传成功，返回id：{}", upload.getId());
                resultMap.put("videoUrl", upload.getUrlPath());
                resultMap.put("videoRef", videoWidth + "x" + videoHeight);
                return JSON.toJSONString(resultMap);
            }
        } catch (Exception e) {
            logger.warn("上传视频文件失败。。。。。。。。", e);
        }
        //todo:上传完之后要删除
        return null;
    }

    public void killRecord() {
        try {
            recorder.stop();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("结束录屏失败。。。。。。", e);
        }
        try {
            recorder.release();
        } catch (FFmpegFrameRecorder.Exception e) {
            logger.warn("释放录屏失败。。。。。。", e);
        }
        File file = new File(filePath + videoName);
        if (file.exists()) {
            file.delete();
        }
        interrupt();
    }
}
