package org.framework.lazy.cloud.network.heartbeat.server.init;

import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.server.cluster.application.LazyNettyClusterNodeApplication;
import org.framework.lazy.cloud.network.heartbeat.server.cluster.domain.model.cluster.node.LazyNettyClusterNode;
import org.framework.lazy.cloud.network.heartbeat.server.cluster.infrastructure.entity.LazyNettyClusterNodeDO;
import org.framework.lazy.cloud.network.heartbeat.server.properties.ServerNodeProperties;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.wu.framework.core.utils.ObjectUtils;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
import org.wu.framework.lazy.orm.database.lambda.stream.wrapper.LazyWrappers;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 当配置模式为集群模式 加载
 */

@ConditionalOnProperty(prefix = ServerNodeProperties.prefix, value = "mode", havingValue = "cluster")
@Configuration
@Slf4j
public class InitClusterNode implements CommandLineRunner, DisposableBean {

    private final LazyNettyClusterNodeApplication lazyNettyClusterNodeApplication;

    private final ServerNodeProperties serverNodeProperties;
    private final LazyLambdaStream lazyLambdaStream;

    public InitClusterNode(LazyNettyClusterNodeApplication lazyNettyClusterNodeApplication,
                           ServerNodeProperties serverNodeProperties,
                           LazyLambdaStream lazyLambdaStream) {
        this.lazyNettyClusterNodeApplication = lazyNettyClusterNodeApplication;
        this.serverNodeProperties = serverNodeProperties;
        this.lazyLambdaStream = lazyLambdaStream;
    }


    @Override
    public void run(String... args) throws Exception {
        log.info("init cluster node....");
        initNodeConfig2Db();
        // 连接所有节点

        lazyNettyClusterNodeApplication.starterClusterNodes();


    }

    public boolean checkConfig(ServerNodeProperties serverNodeProperties) {

        if (
                ObjectUtils.isEmpty(serverNodeProperties.getNodeId()) ||
                        ObjectUtils.isEmpty(serverNodeProperties.getNodeHost()) ||
                        ObjectUtils.isEmpty(serverNodeProperties.getNodePort())
        ) {
            return false;
        }
        return true;

    }

    /**
     * 存储配置到db
     */
    public void initNodeConfig2Db() {

        // 初始化 node 配置信息
        String clusterNodeId = serverNodeProperties.getNodeId();
        String clusterNodeHost = serverNodeProperties.getNodeHost();
        Integer clusterNodePort = serverNodeProperties.getNodePort();

        if (Objects.isNull(clusterNodeId) ||
                Objects.isNull(clusterNodeHost)) {
            log.warn("节点信息错误:{}", serverNodeProperties);
            return;
        }
        LazyNettyClusterNode lazyNettyClusterNode = new LazyNettyClusterNode();
        lazyNettyClusterNode.setClusterNodeHost(clusterNodeHost);
        lazyNettyClusterNode.setClusterNodePort(clusterNodePort);
        lazyNettyClusterNode.setClusterNodeId(clusterNodeId);
        lazyNettyClusterNode.setIsDeleted(false);
        lazyNettyClusterNode.setCreateTime(LocalDateTime.now());
        lazyNettyClusterNode.setUpdateTime(LocalDateTime.now());
        // 根据服务端端口、port 唯一性验证
        boolean exists = lazyLambdaStream.exists(LazyWrappers.<LazyNettyClusterNodeDO>lambdaWrapper()
                .eq(LazyNettyClusterNodeDO::getClusterNodeId, clusterNodeId)
        );
        if (!exists) {
            lazyLambdaStream.insert(lazyNettyClusterNode);
        }
    }

    /**
     * 程序关闭后执行
     */
    @Override
    public void destroy() {
        lazyNettyClusterNodeApplication.destroyClusterNodes();
    }

}
