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

import com.alibaba.fastjson.JSONObject;
import net.northking.cctp.upperComputer.deviceManager.IOSDeviceManager;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @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) {
        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]);
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("获取应用版本失败", e);
        }
        return false;
    }

    @Override
    public boolean removeApp(String deviceId, String appPackage) {
        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);
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                logger.error("卸载手机应用【{}】出错", appPackage, e);
                return false;
            }
        } else {
            return true;
        }
    }

    @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) {
        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);
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            logger.error("卸载手机应用【{}】出错", appPath, e);
            return false;
        }
    }

    @Override
    public boolean activateApp(String deviceId, String appPackage) {
        PhoneEntity phoneEntity = IOSDeviceManager.getInstance().getPhoneEntity(deviceId);
        if (!phoneEntity.getStatus()) {
            throw new ExecuteException("设备不在线，无法启动app");
        }
        String wdaSessionId = IOSDeviceManager.getInstance().getPhoneWdaSessionId(deviceId);
        if (wdaSessionId != null) {
            String url = "http://127.0.0.1:" + phoneEntity.getPort8100() + "/session/" + wdaSessionId + "/wda/apps/state";
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("bundleId", appPackage);
            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(paramMap, null);
            try {
                JSONObject result = HttpUtils.doPost(new URI(url), entity, JSONObject.class);
                int value = result.getIntValue("value");
                if (value == 4) {
                    logger.info("设备【{}】的应用【{}】已经启动并展示在前台", phoneEntity.getUdid(), appPackage);
                    return true;
                }
            } catch (URISyntaxException uriSyntaxException) {
                logger.warn("设备【{}】请求应用【{}】状态时url不对", phoneEntity.getUdid(), appPackage);
            } catch (Exception e) {
                logger.warn("设备【{}】请求应用【{}】状态时出错，待会再试", phoneEntity.getUdid(), appPackage);
            }
        }
//        JSONObject value = HttpUtils.doGet(new URI(url), JSONObject.class);
        String[] cmd = {"tidevice", "-u", deviceId, "launch", appPackage};
        ProcessBuilder builder = new ProcessBuilder().command(cmd);
        builder.redirectErrorStream(true);
        try {
            Process process = builder.start();
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while (null != (line = reader.readLine())) {
                logger.debug(line);
                sb.append(line);
            }
            String result = sb.toString();
            if (result.startsWith("PID:")) {
                return true;
            }
            if (result.contains(LAUNCH_APP_FAIL_FLAG)) {
                logger.warn("手机未信任应用开发者启动失败，放开权限支持录制信任步骤");
                logger.warn("手机启动应用异常：{}", result);
                return true;
            }
        } catch (IOException e) {
            logger.warn("启动app出现错误", e);
        }
        return false;
    }

    /**
     * 截取区域图片，得到文件
     *
     * @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) {
        if (cutWidth <= 0 || cutHeight <= 0) {
            throw new ExecuteException("截取图片的宽高不满足要求");
        }
        File snapShotFile = null;
        File cutFile = null;
        try {
            snapShotFile = ScreenShotUtils.getIOSMobileScreenShot(deviceId);
            if (null == snapShotFile) {
                logger.debug("设备【{}】未截取到图片",deviceId);
                throw new ExecuteException("未截取到图片");
            }
            cutFile = cutImageFile(snapShotFile, deviceId, startX, startY, cutWidth, cutHeight, screenWidth, screenHeight);
            logger.debug("设备【{}】截取到的图片为：{}",deviceId,cutFile.getAbsolutePath());
            return cutFile;
        } catch (ExecuteException e) {
            logger.error("截图失败", e);
            throw e;
        } catch (Exception e) {
            logger.error("截图失败", e);
            throw new ExecuteException("截取图片失败");
        }finally {
            if (null != snapShotFile) {
                //删除
            }
            if (null != cutFile) {
                //删除
            }
        }
    }
}
