package com.vsu.fcounter.tcprelay;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class TcpRelayModule extends ReactContextBaseJavaModule {

    private final byte[][] bytes = {
        {(byte) 0xA0, (byte) 0x01, (byte) 0x01, (byte) 0xA2}, // 1-on
        {(byte) 0xA0, (byte) 0x01, (byte) 0x00, (byte) 0xA1}, // 1-off
        {(byte) 0xA0, (byte) 0x02, (byte) 0x01, (byte) 0xA3}, // 2-on
        {(byte) 0xA0, (byte) 0x02, (byte) 0x00, (byte) 0xA2}, // 2-off
        {(byte) 0xA0, (byte) 0x03, (byte) 0x01, (byte) 0xA4}, // 3-on
        {(byte) 0xA0, (byte) 0x03, (byte) 0x00, (byte) 0xA3}, // 3-off
        {(byte) 0xA0, (byte) 0x04, (byte) 0x01, (byte) 0xA5}, // 4-on
        {(byte) 0xA0, (byte) 0x04, (byte) 0x00, (byte) 0xA4}, // 4-off
    };
    private Map<String, Socket> socketMap = new HashMap<>();

    @NonNull
    @Override
    public String getName() {
        return "TcpRelay";
    }

    private String getHost(String ip, int port) {
        return ip + ':' + port;
    }

    @ReactMethod
    public void isConnected(String ip, int port, Promise promise) {
        new Thread(() -> {
            Socket socket = socketMap.get(getHost(ip, port));
            promise.resolve(socket != null && socket.isConnected());
        });
    }

    @ReactMethod
    public void toggle(String ip, int port, int route, int status, int delay, Promise promise) {
        new Thread(() -> {
            try {
                String host = this.getHost(ip, port);
                Socket socket = socketMap.get(host);
                if (socket == null || !socket.isConnected()) { // 创建socket
                    if (socket != null) socket.close();
                    socket = new Socket(ip, port);
                    socketMap.put(host, socket);
                }
                if (socket.isConnected()) {
                    if (status != 0 && status != 1) {
                        promise.resolve(false);
                        return;
                    }
                    int index = 2 * route - 1 - status;
                    if (index < 0 || index >= bytes.length) {
                        promise.resolve(false);
                        return;
                    }
                    socket.getOutputStream().write(bytes[index]);
                    if (delay > 0 && status == 1) {
                        Thread.sleep(delay);
                        socket.getOutputStream().write(bytes[index + 1]);
                    }
                    promise.resolve(true);
                    return;
                }
                promise.resolve(false);
            } catch (Exception e) {
                e.printStackTrace();
                promise.resolve(false);
            }
        }).start();
    }

}
