package io.wdd.agent.agent;


import io.wdd.agent.config.utils.AgentCommonThreadPool;
import io.wdd.agent.executor.CommandExecutor;
import io.wdd.agent.executor.FunctionExecutor;
import io.wdd.agent.message.OMessageToServerSender;
import io.wdd.common.beans.agent.AgentOperationMessage;
import io.wdd.common.beans.rabbitmq.OctopusMessage;
import io.wdd.common.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import static io.wdd.common.beans.status.OctopusStatusMessage.ALL_AGENT_STATUS_REDIS_KEY;

@Service
@Slf4j
public class AgentRebootUpdateService {

    @Resource
    FunctionExecutor functionExecutor;

    @Resource
    CommandExecutor commandExecutor;

    @Resource
    OMessageToServerSender toServerSender;

    @Resource
    RedisTemplate redisTemplate;

    public void exAgentReboot(AgentOperationMessage operationMessage) {

    }

    public void exAgentUpdate(AgentOperationMessage operationMessage) {

    }

    public void exAgentShutdown(OctopusMessage octopusMessage, AgentOperationMessage operationMessage) {

        LocalDateTime now = TimeUtils.currentTime();
        LocalDateTime operationTime = operationMessage.getOperationTime();
        Duration duration = Duration.between(
                now,
                operationTime
        );

        long seconds = duration.toSeconds();

        // 发送消息至RabbitMQ中
        octopusMessage.setAc_time(now);
        octopusMessage.setResult(
                String.format(
                        "OctopusAgent [ %s ] 将会在 [ %s ] 秒之后关机",
                        octopusMessage.getUuid(),
                        seconds
                )
        );
        toServerSender.send(
                octopusMessage
        );

        ExecutorService pool = AgentCommonThreadPool.pool;

        // 休眠,阻塞当前线程
        if (seconds > 0) {

            pool.submit(
                    () -> {

                        // keep this to local
                        OctopusMessage message = octopusMessage;

                        try {
                            TimeUnit.SECONDS.sleep(seconds);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                        // 执行实际的关机操作
                        doShutdownAgent(message);
                    }
            );

        } else {
            // 不需要等待,直接关机
            doShutdownAgent(octopusMessage);
        }


    }

    private void doShutdownAgent(OctopusMessage octopusMessage) {

        ArrayList<String> shutdownCommand = new ArrayList<>(
                List.of(
                        "systemctl",
                        "poweroff"
                )
        );

        //发送消息至Redis中, 修改Agent的状态
        redisTemplate
                .opsForHash()
                .put(
                        ALL_AGENT_STATUS_REDIS_KEY,
                        octopusMessage.getUuid(),
                        "0"
                );


        // 执行关机操作
        log.error(
                "开始关闭OctopusAgent! 时间为 [ {} ]",
                TimeUtils.currentTimeString()
        );
        String streamKey = octopusMessage.getUuid() + "-Status";

        // 最终执行关机操作
        commandExecutor.execute(
                streamKey,
                shutdownCommand,
                false,
                false,
                null
        );
    }
}
