package cn.reghao.bnt.common.agent.machine;

import cn.reghao.bnt.common.agent.app.iface.AppStat;
import cn.reghao.bnt.common.machine.Machine;
import cn.reghao.bnt.common.msg.MessageSender;
import cn.reghao.bnt.common.msg.event.EvtAgentHeartbeat;
import cn.reghao.bnt.common.msg.event.EvtAgentStart;
import cn.reghao.bnt.common.msg.event.EvtAppStatResult;
import cn.reghao.jutil.jdk.event.message.EventMessage;
import cn.reghao.jutil.jdk.thread.ThreadPoolWrapper;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author reghao
 * @date 2021-09-03 09:22:42
 */
@Slf4j
public class MachineEvent {
    private final ScheduledExecutorService scheduler;
    private ScheduledFuture<?> heartbeatFuture;
    private final Machine machine;
    private final AppStat appStat;
    private final MessageSender messageSender;
    private final int heartbeatInterval;
    
    public MachineEvent(MessageSender messageSender, Machine machine, AppStat appStat,
                        ScheduledExecutorService scheduler, int heartbeatInterval) {
        this.messageSender = messageSender;
        this.machine = machine;
        this.appStat = appStat;
        this.scheduler = scheduler;
        this.heartbeatInterval = heartbeatInterval;
    }

    public void agentStart() {
        EvtAgentStart evtAgentStart = machine.detail();
        EventMessage eventMessage = EventMessage.evt(evtAgentStart);
        pub(eventMessage);

        try {
            List<EvtAppStatResult> list = appStat.stat();
            list.forEach(evtAppStatResult -> {
                EventMessage eventMessage1 = EventMessage.evt(evtAppStatResult);
                pub(eventMessage1);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

        agentHeartbeat();
    }

    public void agentShutdown() {
        ThreadPoolWrapper.shutdownScheduler(scheduler);
        EvtAgentHeartbeat machineStat = machine.stat();
        EventMessage eventMessage = EventMessage.evt(machineStat);
        pub(eventMessage);
    }

    public void agentHeartbeat() {
        heartbeatFuture = scheduler.scheduleAtFixedRate(new Heartbeat(), 5, heartbeatInterval, TimeUnit.SECONDS);
    }

    public void pauseHeartbeat() {
        if (!heartbeatFuture.isCancelled()) {
            heartbeatFuture.cancel(true);
        }
    }

    private void pub(EventMessage eventMessage) {
        if (messageSender.isConnected()) {
            try {
                messageSender.send("", eventMessage);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            log.error("连接断开");
        }
    }

    class Heartbeat implements Runnable {
        @Override
        public void run() {
            EvtAgentHeartbeat machineStat = machine.stat();
            EventMessage eventMessage = EventMessage.evt(machineStat);
            pub(eventMessage);
        }
    }
}
