package net.northking.cctp.upperComputer.driver.harmony.hdc;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 端口转发规则
 */
public class ForwardRule {

    private final Logger logger = LoggerFactory.getLogger(ForwardRule.class);
    /**
     * 设备key
     */
    private final String connectKey;

    /**
     * 设备端监听Scheme
     */
    private final ListenScheme deviceScheme;

    /**
     * 设备端监听的名称，根据不同的scheme，可能是监听的名称，也可能是端口
     */
    private final String deviceContent;

    /**
     * 本机端监听Scheme
     */
    private final ListenScheme localScheme;

    /**
     * 本机监听的名称，根据不同的scheme，可能是监听的名称，也可能是端口
     */
    private final String localContent;

    /**
     * 是否为反向转发。<br>
     * 请求从本机流向设备端内部，为正向<br>
     * 请求从设备端流向本机，为反向
     */
    private final boolean reverse;

    public ForwardRule(String connectKey, ListenScheme deviceScheme, String deviceContent, ListenScheme localScheme, String localContent, boolean reverse) {
        this.connectKey = connectKey;
        this.deviceScheme = deviceScheme;
        this.deviceContent = deviceContent;
        this.localScheme = localScheme;
        this.localContent = localContent;
        this.reverse = reverse;
    }

    public ForwardRule(String fullTaskString) {
        String[] baseSplit = fullTaskString.split(" {4}");
        if (baseSplit.length != 3) {
            throw new IllegalArgumentException("无法处理的端口转发规则内容[无法处理基础分割]：" + fullTaskString);
        }
        this.connectKey = baseSplit[0];
        this.reverse = baseSplit[2].equals("[Reverse]");

        String[] baseTaskInfo = baseSplit[1].split(" ");
        if (baseTaskInfo.length != 2) {
            throw new IllegalArgumentException("无法处理的端口转发规则内容[无法处理端口转发任务信息分割]：" + fullTaskString);
        }
        String[] firstInfos = baseTaskInfo[0].split(":");
        if (firstInfos.length != 2) {
            throw new IllegalArgumentException("无法处理第一个转发规则内容：" + fullTaskString);
        }
        String[] secondInfos = baseTaskInfo[1].split(":");
        if (secondInfos.length != 2) {
            throw new IllegalArgumentException("无法处理第二个转发规则内容：" + fullTaskString);
        }
        if (this.reverse) {
            this.deviceScheme = ListenScheme.fromString(firstInfos[0]);
            this.deviceContent = firstInfos[1];

            this.localScheme = ListenScheme.fromString(secondInfos[0]);
            localContent = secondInfos[1];
        } else {
            this.localScheme = ListenScheme.fromString(firstInfos[0]);
            this.localContent = firstInfos[1];

            this.deviceScheme = ListenScheme.fromString(secondInfos[0]);
            deviceContent = secondInfos[1];
        }
    }

    public boolean isReverse() {
        return reverse;
    }

    /**
     * 设备部分监听信息
     * @return 监听指令规则
     */
    public String deviceString() {
        return deviceScheme.getScheme() + ":" + deviceContent;
    }

    /**
     * 本地部分监听信息
     *
     * @return 监听指令规则
     */
    public String localString() {
        return localScheme.getScheme() + ":" + localContent;
    }

    /**
     * 规则文本
     *
     * @return 规则文本
     */
    public String taskString() {
        if (reverse) {
            return deviceString() + " " + localString();
        } else {
            return localString() + " " + deviceString();
        }
    }

    public String getConnectKey() {
        return connectKey;
    }

    public ListenScheme getDeviceScheme() {
        return deviceScheme;
    }

    public String getDeviceContent() {
        return deviceContent;
    }

    public ListenScheme getLocalScheme() {
        return localScheme;
    }

    public String getLocalContent() {
        return localContent;
    }

    @Override
    public String toString() {
        return "ForwardRule{" +
                "connectKey='" + connectKey + '\'' +
                ", deviceScheme=" + deviceScheme +
                ", deviceContent='" + deviceContent + '\'' +
                ", localScheme=" + localScheme +
                ", localContent='" + localContent + '\'' +
                ", reverse=" + reverse +
                '}';
    }

    /**
     * 监听协议
     */
    public enum ListenScheme {
        TCP("tcp"),
        LOCAL_FILE_SYSTEM("localfilesystem"),
        LOCAL_RESERVED("localreserved"),
        LOCAL_ABSTRACT("localabstract"),
        DEV("dev"),
        JDWP("jdwp");
        private final String scheme;

        ListenScheme(String s) {
            this.scheme = s;
        }

        public String getScheme() {
            return scheme;
        }

        public static ListenScheme fromString(String s) {
            for (ListenScheme listenScheme : values()) {
                if (listenScheme.getScheme().equals(s)) {
                    return listenScheme;
                }
            }
            throw new IllegalArgumentException("Unknown Scheme");
        }
    }
}
