package com.sv.socket;

import com.common.DeviceDTO;
import com.sv.entity.Device;
import com.sv.socket.event.SocketConnectEvent;
import com.sv.socket.event.SocketMessageEvent;
import com.sv.socket.event.SocketReconnectEvent;
import com.ydd.framework.core.common.utils.ValidationUtils;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationContext;

import javax.annotation.Resource;
import java.net.URI;
import java.util.concurrent.CountDownLatch;

/**
 * 设备连接
 */
public class DeviceSocket extends WebSocketClient {

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

    private DeviceDTO device;

    private CountDownLatch countDownLatch;


    @Resource
    private ApplicationContext applicationContext;

    public DeviceSocket(ApplicationContext applicationContext, DeviceDTO device, URI serverUri) {
        super(serverUri);
        ValidationUtils.assertNotNull(device);
        this.device = device;
        this.applicationContext = applicationContext;
        countDownLatch = new CountDownLatch(1);
    }

    @Override
    public void onOpen(ServerHandshake handshakedata) {
        applicationContext.publishEvent(new SocketConnectEvent(device, countDownLatch, DeviceSocket.this));
    }

    @Override
    public void onMessage(String message) {
        logger.info("收到设备" + device.getName() + "消息:" + message);
        applicationContext.publishEvent(new SocketMessageEvent(message, device));
    }

    @Override
    public void onClose(int code, String reason, boolean remote) {
        logger.info("设备【{}】断开连接，code:【{}】,reason:【{}】", device.getStream(), code, reason);
        SocketConnections.sockets.remove(device.getStream());
        countDownLatch.countDown();
        if (device.getLastCloseTime() == null)
            device.setLastCloseTime(System.currentTimeMillis());
        applicationContext.publishEvent(new SocketReconnectEvent(device));
    }

    @Override
    public void onError(Exception ex) {
        SocketConnections.sockets.remove(device.getStream());
    }


    public DeviceDTO getDevice() {
        return device;
    }


    public String getStreamName() {
        return device.getStream();
    }
}
