package com.ruoyi.system.core.clientExecute;


import com.ruoyi.system.core.*;
import com.ruoyi.system.core.annotate.Execute;
import com.ruoyi.system.core.domain.DeviceFunc;
import com.ruoyi.system.domain.SysDevice;
import com.ruoyi.system.domain.SysDeviceCommand;
import org.springframework.stereotype.Component;
import org.tio.client.ClientChannelContext;
import org.tio.client.ClientTioConfig;
import org.tio.client.ReconnConf;
import org.tio.client.TioClient;
import org.tio.core.Node;
import org.tio.core.Tio;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

@Execute(type = "TCP")
@Component
public class TcpStart implements ClientExecute {
    @Resource
    private ClientTioHandler clientTioHandler;

    @Resource
    private ClientAioListenerImpl clientAioListener;


    public static HashMap<String, ClientChannelContext> map = new HashMap<>();


    @Override
    public void createClient(SysDevice device) {
        ReconnConf reconnConf = new ReconnConf();
        reconnConf.setRetryCount(3);
        reconnConf.setInterval(500);
        ClientTioConfig clientTioConfig = new ClientTioConfig(clientTioHandler, clientAioListener, reconnConf);
        TioClient tioClient = null;
        try {
            tioClient = new TioClient(clientTioConfig);
            map.put(device.getDeviceNo(), tioClient.connect(new Node(device.getIp(), device.getPort().intValue())));
            this.getInstruct(DeviceInstructType.ID_ENTITY, device.getDeviceType()).subscribe(x -> {
                DeviceFunc deviceFunc = new DeviceFunc();
                deviceFunc.setMessage(x.getCommand());
                boolean send = this.send(device, deviceFunc);
                if (!send) {
                    throw new RuntimeException("设备身份上报失败");
                }
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean send(SysDevice device, DeviceFunc msg) {
        ClientChannelContext clientChannelContext = map.get(device.getDeviceNo());
        if (clientChannelContext == null) {
            return false;
        }
        MindPackage mindPackage = new MindPackage();
        mindPackage.setBody(msg.getMessage().getBytes(StandardCharsets.UTF_8));
        return Tio.send(clientChannelContext, mindPackage);
    }

    @Override
    public boolean connection(SysDevice device) {
        return false;
    }

    @Override
    public void close(SysDevice device) {
        ClientChannelContext clientChannelContext = map.get(device.getDeviceNo());
        if (clientChannelContext == null || clientChannelContext.isClosed) {
            return;
        }
        Tio.remove(clientChannelContext, "移除");
    }

    @Override
    public Mono<SysDeviceCommand> getInstruct(String receive, String deviceType) {
        return Mono.empty();
    }

    @Override
    public Mono<SysDeviceCommand> getByFunc(String funcId, String deviceType) {
        return null;
    }
}
