package net.geedge.api.util;

import net.geedge.common.T;

import java.util.LinkedList;
import java.util.List;

public class AdbCommandBuilder {

    private final String adbPath;
    private final List<String> command;

    public AdbCommandBuilder(String adbPath) {
        this.adbPath = adbPath;
        this.command = new LinkedList<>();
        this.command.add(adbPath);
    }

    public static AdbCommandBuilder builder() {
        return new AdbCommandBuilder("adb");
    }

    public static AdbCommandBuilder builder(String adbPath) {
        return new AdbCommandBuilder(adbPath);
    }

    public AdbCommandBuilder serial(String serial) {
        this.command.add("-s");
        this.command.add(serial);
        return this;
    }

    public AdbCommandBuilder buildConnectCommand(String host, Integer port) {
        this.command.add("connect");
        this.command.add(String.format("%s:%s", host, port));
        return this;
    }

    public AdbCommandBuilder buildDevicesCommand() {
        this.command.add("devices");
        this.command.add("-l");
        return this;
    }

    public AdbCommandBuilder buildRootCommand() {
        this.command.add("root");
        return this;
    }

    public AdbCommandBuilder buildGetpropCommand() {
        this.command.add("shell");
        this.command.add("getprop");
        return this;
    }

    public AdbCommandBuilder buildWmSizeCommand() {
        this.command.add("shell");
        this.command.add("wm");
        this.command.add("size");
        return this;
    }

    public AdbCommandBuilder buildCheckRootCommand() {
        this.command.add("shell");
        this.command.add("ls");
        this.command.add("/data");
        return this;
    }

    /**
     * 指定 String cmd 执行，解决命令过长阅读性较差问题
     */
    public AdbCommandBuilder buildShellCommand(String shellCmd) {
        String[] strings = T.CommandLineUtil.translateCommandline(shellCmd);
        for (String string : strings) {
            this.command.add(string);
        }
        return this;
    }

    public AdbCommandBuilder buildPushCommand(String local, String remote) {
        this.command.add("push");
        this.command.add(local);
        this.command.add(remote);
        return this;
    }

    public AdbCommandBuilder buildPullCommand(String remote, String local) {
        this.command.add("pull");
        this.command.add(remote);
        this.command.add(local);
        return this;
    }

    public AdbCommandBuilder buildLsDirCommand(String path) {
        this.command.add("shell");
        this.command.add("ls");
        this.command.add("-l");
        this.command.add(path);
        return this;
    }

    public AdbCommandBuilder buildPmListPackagesCommand(String arg) {
        this.command.add("shell");
        this.command.add("pm");
        this.command.add("list");
        this.command.add("packages");
        if (T.StrUtil.isNotEmpty(arg)) {
            this.command.add(arg);
        }
        return this;
    }

    public AdbCommandBuilder buildCheckPackage(String packageName) {
        this.command.add("shell");
        this.command.add("pm");
        this.command.add("list");
        this.command.add("packages");
        this.command.add("-3");
        this.command.add(packageName);
        return this;
    }

    public AdbCommandBuilder buildFindPackageNameList() {
        this.command.add("shell");
        this.command.add("pm");
        this.command.add("list");
        this.command.add("packages");
        this.command.add("-3");
        return this;
    }

    public AdbCommandBuilder buildStartAPP(String packageName) {
        this.command.add("shell");
        this.command.add("monkey");
        this.command.add("-p");
        this.command.add(packageName);
        this.command.add("-c");
        this.command.add("android.intent.category.LAUNCHER");
        this.command.add("1");
        return this;
    }

    public AdbCommandBuilder buildMd5sumCommand(String path) {
        this.command.add("shell");
        this.command.add("md5sum");
        this.command.add(path);
        return this;
    }

    public AdbCommandBuilder buildInstallCommand(String localFilePath, boolean isDebugApk, boolean isReInstall) {
        this.command.add("install");
        if (isDebugApk) {
            this.command.add("-d");
        }
        if (isReInstall) {
            this.command.add("-r");
        }
        this.command.add(localFilePath);
        return this;
    }

    public AdbCommandBuilder buildUnInstallCommand(String packageName) {
        this.command.add("uninstall");
        this.command.add(packageName);
        return this;
    }

    public AdbCommandBuilder buildIptablesLnRulesCommand(String chainName) {
        this.command.add("shell");
        this.command.add("iptables");
        this.command.add("-nL");
        this.command.add(chainName);
        this.command.add("--line-numbers");
        return this;
    }

    public AdbCommandBuilder buildIptablesAddRuleCommand(String chainName, String protocol, String ip, String port) {
        this.command.add("shell");
        this.command.add("iptables");
        this.command.add("-A");
        this.command.add(chainName);
        this.command.add("-p");
        this.command.add(protocol);

        if (T.StrUtil.isNotEmpty(ip)) {
            this.command.add("-d");
            this.command.add(ip);
        }

        if (T.StrUtil.isNotEmpty(port) && !"all".equals(protocol)) {
            this.command.add("--dport");
            this.command.add(port);
        }

        this.command.add("-j");
        this.command.add("ACCEPT");
        return this;
    }

    public AdbCommandBuilder buildIptablesDelRuleCommand(String chainName, String protocol, String ip, String port) {
        this.command.add("shell");
        this.command.add("iptables");
        this.command.add("-D");
        this.command.add(chainName);
        this.command.add("-p");
        this.command.add(protocol);

        if (T.StrUtil.isNotEmpty(ip)) {
            this.command.add("-d");
            this.command.add(ip);
        }

        if (T.StrUtil.isNotEmpty(port) && !"all".equals(protocol)) {
            this.command.add("--dport");
            this.command.add(port);
        }

        this.command.add("-j");
        this.command.add("ACCEPT");
        return this;
    }

    public AdbCommandBuilder buildIptablesFlushRuleCommand(String chainName) {
        this.command.add("shell");
        this.command.add("iptables");
        this.command.add("-F");
        this.command.add(chainName);
        return this;
    }


    public List<String> build() {
        return this.command;
    }

    public AdbCommandBuilder buildStopAppCommand(String packageName) {
        this.command.add("shell");
        this.command.add("am");
        this.command.add("force-stop");
        this.command.add(packageName);
        return this;
    }

    public AdbCommandBuilder buildClearAppDateCommand(String packageName) {
        this.command.add("shell");
        this.command.add("pm");
        this.command.add("clear");
        this.command.add(packageName);
        return this;
    }
}