package com.pwt.netty;

import cn.hutool.core.thread.NamedThreadFactory;
import com.pwt.netty.message.WebSocketMessage;
import com.pwt.netty.util.WebSocketUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class MessageSender {

    public static final String MSG_ALL_DATA = "allData";

    public static final String MSG_OPERATION_DATA = "operationData";
    public static final String MSG_ASSIST = "assist";

    public static final String MSG_VEHICLE_FLOW_STATE = "vehicleState";

    public static final String MSG_VEHICLE_INFO = "vehicleInfo";

    public static final String MSG_ROBOT = "robot";
    public static final String MSG_RFID = "rfid";
    public static final String MSG_EXCHANGE_WORK_MODE = "exchangeWorkMode";

    public static final String MSG_EXCHANGE_PROCESS = "exchangeState";

    public static final String MSG_CHARGERS = "chargers";
    public static final String MSG_GUNS = "chargerGuns";

    public static final String MSG_ALARM = "alarms";

    public static final String MSG_ALARM_STATISTICS = "alarmStats";
    public static final String MSG_CHANGE_HOLDER_INFO = "changeHolderInfo";
    public static final String MSG_BATTER_INFOS = "batteryInfos";
    public static final String MSG_BATTER_STATES = "batteryStates";

    public static final String SYSTEM_CONFIG = "systemConfig";


    public static void send(String key, Object data) {
        EXECUTOR.execute(new SingleMessageSenderTask(key, data));
    }

    public static void send(Map<String, Object> dataBundle) {

        if (dataBundle == null) {
            return;
        }
        List<WebSocketMessage> msgList = new ArrayList<>(dataBundle.size());
        for (Map.Entry<String, Object> entry : dataBundle.entrySet()) {
            msgList.add(WebSocketMessage.build(entry.getKey(), entry.getValue()));
        }

        if (msgList.size() == 0) {
            return;
        }
        WebSocketUtil.pushMsgToAll(msgList);
    }

    private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(1, Integer.MAX_VALUE, 3L, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(1000), new NamedThreadFactory("message-sender", true), new ThreadPoolExecutor.DiscardPolicy() {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (log.isDebugEnabled()) {
                log.debug("discard a task");
            }
        }
    });


    static class SingleMessageSenderTask implements Runnable {

        private final String key;
        private final Object data;

        public SingleMessageSenderTask(String key, Object data) {
            this.key = key;
            this.data = data;
        }

        @Override
        public void run() {
            WebSocketUtil.pushMsgToAll(WebSocketMessage.build(key, data));
        }
    }
}
