package net.northking.cctp.upperComputer.service;

import net.northking.cctp.upperComputer.config.MobileProperty;
import net.northking.cctp.upperComputer.deviceManager.UpperComputerManager;
import net.northking.cctp.upperComputer.entity.DebuggerDeviceInfo;
import net.northking.cctp.upperComputer.utils.ios.IosDeviceHandleHelper;
import net.northking.cctp.upperComputer.utils.ios.LinuxAndWindowsIosHandleHelper;
import net.northking.cctp.upperComputer.utils.ios.MacIosHandleHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class AbstractDebuggerService implements DebuggerService {

    protected MobileProperty mobileProperty;

    protected IosDeviceHandleHelper deviceHandleHelper;

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

    public AbstractDebuggerService() {
        boolean isMac = UpperComputerManager.getInstance().getOperatingSystem().startsWith("Mac");
        if (isMac) {
            deviceHandleHelper = new MacIosHandleHelper();
        } else {
            deviceHandleHelper = new LinuxAndWindowsIosHandleHelper();
        }
    }

    @Override
    public String downloadApp(String appId, String appName) {
        return deviceHandleHelper.downloadAppToLocal(appId, appName);
    }

    public void setMobileProperty(MobileProperty mobileProperty) {
        this.mobileProperty = mobileProperty;
    }

    @Override
    public boolean isAppInstalled(String deviceId, String appPackage) {
        return false;
    }

    @Override
    public boolean removeApp(String deviceId, String appPackage) {
        return false;
    }

    @Override
    public boolean installApp(String deviceId, String appPath) {
        return false;
    }

    @Override
    public String execShellWaitResult(String shell, String dir, Map<String,String> envMap,boolean isWaitOrNot) {
        String result = null;
        List<String> cmds = new ArrayList<>();
        cmds.add("/bin/bash");
        cmds.add("-c");
        cmds.add(shell);
        ProcessBuilder processBuilder = new ProcessBuilder().command(cmds);
        if (null != dir) {
            processBuilder.directory(new File(dir));
        }
        if (null != envMap && !CollectionUtils.isEmpty(envMap)) {
            Map<String, String> environment = processBuilder.environment();
            environment.putAll(envMap);
        }
        processBuilder.redirectErrorStream(true);
        try {
            Process start = processBuilder.start();
            if (isWaitOrNot) {
                InputStream inputStream = start.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String line = null;
                StringBuilder sb = new StringBuilder();
                while (null != (line = reader.readLine())) {
                    sb.append(line);
                }
                result = sb.toString();
            }
        } catch (IOException e) {
            logger.error("执行命令：{}出错",shell,e);
        }
        return result;
    }

    @Override
    public boolean activeApp(String deviceId, String appPackage) {
        return false;
    }

    protected String regularSub(String xml, String reg, String target) {
        Pattern r = Pattern.compile(reg);
        Matcher m = r.matcher(xml);
        while (m.find()) {
            String group = m.group();
            if (!"<hierarchy ".equals(group) && !"</hierarchy>".equals(group)) {
                xml = xml.replace(group, target);
            }
        }
        return xml;
    }

    protected String pathToId(String tenantId,String path){
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        if (path.endsWith("/")) {
            path = path.substring(0, path.length() - 1);
        }
        String str = path.replaceAll("/", "_");
        return tenantId + str;
    }

    @Override
    public boolean recordDevicePer(DebuggerDeviceInfo info) {
        return false;
    }

    @Override
    public String[] stopRecordDevicePer(DebuggerDeviceInfo info) {
        return new String[0];
    }

    @Override
    public boolean releaseAdbForwardPort(String deviceId) {
        return false;
    }
}
