package org.nl.config.lucene.remote;

import ch.qos.logback.classic.spi.ILoggingEvent;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.nl.config.MapOf;
import org.nl.config.lucene.AsyncLuceneAppender;
import org.nl.config.lucene.remote.impl.ClientServer;
import org.nl.config.lucene.remote.impl.RemoteServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.SmartLifecycle;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;

/*
 * @author ZZQ
 * @Date 2024/1/22 09:06
 */
//@Component
public class RemoteLogServer implements SmartLifecycle {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public static volatile Boolean LOCAL_LOG = Boolean.TRUE;

    private Integer port = 20888;

    public static AbstraceServer server;

    public static AsyncLuceneAppender asyncLuceneAppender;

    public static void writeLog(ILoggingEvent event){
        if (LOCAL_LOG){
            asyncLuceneAppender.appendSync(event);
        }else {
            ByteBuf log = Unpooled.copiedBuffer(JSON.toJSONString(event), CharsetUtil.UTF_8);
            server.channel.writeAndFlush(log);
        }
    };

    @SneakyThrows
    @Override
    public void start() {
        try {
            String provider = redisTemplate.opsForValue().get("providers");
            if (StringUtils.isEmpty(provider)){
                String ip = Inet4Address.getLocalHost().getHostAddress();
                Map<String,Object> config = MapOf.of("ip", ip, "port", port);
                redisTemplate.opsForValue().set("provider", JSON.toJSONString(config));
                Runtime.getRuntime().addShutdownHook(new Thread(() ->{
                    System.out.println("------服务关闭-升级从变主-------");
                    server.doDestroy();
                    redisTemplate.delete("providers");
                    try {
                        Thread.sleep(5000);
                    }catch (Exception ex){}
                }));
                server = new RemoteServer(new InetSocketAddress(ip, port));
                LOCAL_LOG =Boolean.TRUE;
            }else {
                Map<String,String> map = JSONObject.parseObject(provider, HashMap.class);
                String ip = map.get("ip");
                Integer port = Integer.valueOf(map.get("port"));
                server = new ClientServer(new InetSocketAddress(ip, port));
                LOCAL_LOG = Boolean.FALSE;
            }
        }catch (Exception ex){
            ex.printStackTrace();
            throw ex;
        }


    }

    @Override
    public void stop() {

    }

    @Override
    public boolean isRunning() {
        return false;
    }
}
