package net.northking.cctp.upperComputer.utils.ios;

import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
import net.northking.cctp.upperComputer.deviceManager.thread.IosDeviceInitThread;
import net.northking.cctp.upperComputer.driver.ios.NKAgent;
import net.northking.cctp.upperComputer.driver.ios.command.data.ScreenShotData;
import net.northking.cctp.upperComputer.entity.PhoneEntity;
import net.northking.cctp.upperComputer.exception.ExecuteException;
import net.northking.cctp.upperComputer.utils.HttpUtils;
import net.northking.cctp.upperComputer.utils.ScreenShotUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author : yineng.huang
 * @date : 2024/4/24 16:44
 */
public class LinuxAndWindowsIosHandleHelper extends IosDeviceHandleHelper {

    private final Logger logger = LoggerFactory.getLogger(LinuxAndWindowsIosHandleHelper.class);

    @Override
    public boolean isAppInstalled(String deviceId, String appPackage) {
        boolean success = false;
        int count = 0;
        do {
            String line = "";
            String[] cmds = {"tidevice", "-u", deviceId, "applist"};
            ProcessBuilder builder = new ProcessBuilder(Arrays.asList(cmds)).redirectErrorStream(true);
            Process process = null;
            try {
                process = builder.start();
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                while ((line = in.readLine()) != null) {
                    if (line.contains(appPackage)) {
                        String[] split = line.split(" ");
                        if (split.length == 3) {
                            logger.debug("手机应用版本为:{}", split[2]);
                            success =  true;
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("获取应用版本失败", e);
                success = false;
            }
            count++;
        } while (!success && count < 3);
        return success;
    }

    @Override
    public boolean removeApp(String deviceId, String appPackage) {
        boolean success = false;
        int count = 0;
        do {
            if (isAppInstalled(deviceId, appPackage)) {
                String[] cmds = {"tidevice", "-u", deviceId, "uninstall", appPackage};
                ProcessBuilder builder = new ProcessBuilder(Arrays.asList(cmds)).redirectErrorStream(true);
                Process process = null;
                String result = null;
                try {
                    StringBuilder sb = new StringBuilder();
                    process = builder.start();
                    BufferedReader in = new BufferedReader(new InputStreamReader(
                            process.getInputStream()));
                    while (null != (result = in.readLine())) {
                        logger.debug("卸载app【{}】结果：{}", appPackage, result);
                        sb.append(result);
                    }
                    String s = sb.toString();
                    if (s.endsWith("Complete")) {
                        logger.debug("手机应用【{}】卸载完成。。。。。。。。。。", appPackage);
                        success = true;
                    } else {
                        success = false;
                    }
                } catch (Exception e) {
                    logger.error("卸载手机应用【{}】出错", appPackage, e);
                    success = false;
                }
            } else {
                success = true;
            }
            count++;
        } while (!success && count < 3);
        return success;
    }

    @Override
    public String getOldPackageCode(String deviceId, String appPackage) {
        String oldPackageCode = "";
        String[] cmd = {"tidevice", "-u", deviceId, "applist"};
        try {
            ProcessBuilder builder = new ProcessBuilder(Arrays.asList(cmd)).redirectErrorStream(true);
            Process process = builder.start();
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = in.readLine()) != null) {
                if (line.startsWith(appPackage)) {
                    String[] split = line.split(" ");
                    if (split.length == 3) {
                        oldPackageCode = split[2];
                        return oldPackageCode;
                    }
                }
            }

        } catch (Exception e) {
            logger.error("获取应用版本失败", e);
        }
        logger.debug("手机应用版本为:" + oldPackageCode);
        return oldPackageCode;
    }

    @Override
    public  boolean installApp(String deviceId, String appPath) {
        boolean success = false;
        int count = 0;
        do {
            String[] cmds = {"tidevice", "-u", deviceId, "install", appPath};
            ProcessBuilder builder = new ProcessBuilder().command(Arrays.asList(cmds)).redirectErrorStream(true);
            Process process = null;
            String result = null;
            try {
                StringBuilder sb = new StringBuilder();
                process = builder.start();
                BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
                while (null != (result = in.readLine())) {
                    logger.debug("安装app【{}】结果：{}", appPath, result);
                    sb.append(result);
                }
                String s = sb.toString();
                logger.debug("打印的安装结果：{}", s);
                process.waitFor();
                if (!s.contains("Fail")) {
                    logger.debug("手机应用【{}】安装完成。。。。。。。。。。", appPath);
                    success = true;
                } else {
                    success = false;
                }
            } catch (Exception e) {
                logger.error("卸载手机应用【{}】出错", appPath, e);
                success = false;
            }
            count++;
        } while (!success && count < 3);
        return success;
    }

    @Override
    public boolean activateApp(String deviceId, String appPackage) {
        boolean success = false;
        int times = 0;
        while (!success && times < 3) {
            try {
                NKAgent nkAgent = getNkAgent(deviceId);
                String bundleId = nkAgent.activeAppBundleId();
                logger.info("设备【{}】的当前启动的应用为【{}】，传过来要启动的应用为【{}】", deviceId, bundleId, appPackage);
                if (StringUtils.equals(bundleId, appPackage)) {
                    logger.info("设备【{}】的应用【{}】已经启动并展示在前台", deviceId, appPackage);
                    success = true;
                } else {
                    logger.info("设备【{}】的应用【{}】未展示在前台，开始启动", deviceId, appPackage);
                    success = nkAgent.launchApp(appPackage);
                    logger.debug("设备【{}】启动app【{}】的结果：{}", deviceId, appPackage, success);
                }

            } catch (Exception e) {
                logger.error("启动应用失败，e：", e);
            }
            if (!success) {
                try {
                    // 如果失败是因为agent失效，等待重新创建
                    Thread.sleep(5000L);
                } catch (InterruptedException e) {
                    logger.error("启动app休眠打断。");
                }
            }
            times++;
        }
        return success;
    }

    /**
     * 截取区域图片，得到文件
     * 如果x y没有值，则返回全屏图片
     *
     * @param deviceId
     * @param startX
     * @param startY
     * @param cutWidth
     * @param cutHeight
     * @param screenWidth
     * @param screenHeight
     * @return
     */
    @Override
    public  File getScreenShotFile(String deviceId, Integer startX, Integer startY, Integer cutWidth, Integer cutHeight, Integer screenWidth, Integer screenHeight) {
        int screenShotTime = 1;
        while (screenShotTime <= 3) {
            logger.debug("设备【{}】第{}次截图开始.................", deviceId, screenShotTime);
            NKAgent nkAgent = getNkAgent(deviceId);
            ScreenShotData screenShotData = nkAgent.screenShot();
            logger.debug("设备【{}】第{}次截图的大小：{}", deviceId, screenShotTime, screenShotData.dataLength);
            if (screenShotData.dataLength > 0) {
                File file = null;
                File screenShotFile = null;
                FileOutputStream fileOutputStream = null;
                try {
                    File picDir = new File(UpperComputerManager.getInstance().getApplicationPath() + "/tempPic");
                    if (!picDir.exists()) {
                        picDir.mkdirs();
                    }
                    screenShotFile = new File(picDir.getAbsolutePath() + "/" + UUID.randomUUID() + ".jpg");
                    fileOutputStream = new FileOutputStream(screenShotFile);
                    fileOutputStream.write(screenShotData.data);
                    fileOutputStream.flush();
                    logger.debug("设备【{}】第{}次截图在磁盘的位置为：{}", deviceId, screenShotTime, screenShotFile.getAbsolutePath());
                    if (null != startX && null != startY) {
                        if (cutWidth <= 0 || cutHeight <= 0) {
                            throw new ExecuteException("截取图片的宽高不满足要求");
                        }
                        file = cutImageFile(screenShotFile, deviceId, startX, startY, cutWidth, cutHeight, screenWidth, screenHeight);
                        logger.debug("设备【{}】截取到的图片为：{}",deviceId,file.getAbsolutePath());
                    } else {
                        file = screenShotFile;
                    }
                    logger.debug("截取出来的图像为：{}", file.getAbsolutePath());
                    return file;
                } catch (IOException e) {
                    logger.error("截图写入磁盘失败", e);
                } finally {
                    if (null != fileOutputStream) {
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (null != screenShotFile) {
                        //删除
                    }
                    if (null != file) {
                        //删除
                    }
                }
            }
            screenShotTime++;
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        throw new ExecuteException("设备截图失败");
    }

    private NKAgent getNkAgent(String deviceId) {
        int times = 0;
        NKAgent nkAgent = null;
        while (nkAgent == null && times < 3) {
            IosDeviceInitThread iosInitThread = IOSDeviceManager.getInstance().getIosInitThread(deviceId);
            if (null == iosInitThread || !iosInitThread.isAlive() || iosInitThread.isInterrupted()) {
                throw new ExecuteException("设备已经掉线，请重新接入设备");
            }
            try {
                nkAgent = iosInitThread.getNkAgent();
                if (!nkAgent.getStatus()) {
                    throw new ExecuteException("设备Agent还未准备好，稍后再试");
                }
            } catch (Exception e) {
                logger.error("创建nkAgent失败，e", e);
                nkAgent = null;
            }
            if (nkAgent == null) {
                try {
                    // 如果失败是因为agent失效，等待重新创建
                    logger.debug("nkAgent重试创建{}次", times);
                    Thread.sleep(5000L);
                } catch (InterruptedException e) {
                    logger.error("启动app休眠打断。");
                }
            }
            times++;
        }
        return nkAgent;
    }
}
