package com.twjitm.core.common.service.rpc.service;

import com.twjitm.core.common.config.global.GlobalConstants;
import com.twjitm.core.common.config.global.NettyGameRpcConfig;
import com.twjitm.core.common.config.global.NettyGameServiceConfig;
import com.twjitm.core.common.config.rpc.RpcServerConfig;
import com.twjitm.core.common.service.IService;
import com.twjitm.core.common.service.rpc.client.NettyRpcFuture;
import com.twjitm.core.spring.SpringServiceManager;
import com.twjitm.threads.common.executor.NettyOrderThreadPoolExecutor;
import com.twjitm.threads.thread.NettyThreadNameFactory;
import com.twjitm.threads.utils.ExecutorUtil;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.*;

/**
 * @author twjitm - [Created on 2018-08-20 11:51]
 * @company https://github.com/twjitm/
 * @jdk java version "1.8.0_77"
 */
@Service
public class NettyRPCFutureService implements IService {
    /**
     * 定时任务调度器
     */
    private ScheduledExecutorService executorService;

    private ConcurrentHashMap<String, NettyRpcFuture> pendingRPC = new ConcurrentHashMap<>();
    @Override
    public String getId() {
        return NettyRPCFutureService.class.getSimpleName();
    }

    @Override
    public void startup() throws Exception {
        NettyThreadNameFactory nettyThreadNameFactory = new
                NettyThreadNameFactory(GlobalConstants.Thread.DETECT_RPC_PEND_ING);

        //TODO 优化
        NettyGameServiceConfig gameServiceConfig = SpringServiceManager.getSpringLoadService().getNettyGameServiceConfigService().getNettyGameServiceConfig();
        executorService = Executors.newScheduledThreadPool(gameServiceConfig.getRpcConnectThreadSize(), nettyThreadNameFactory);
        executorService.scheduleAtFixedRate(() -> {
            ConcurrentHashMap<String, NettyRpcFuture> pendingRPC = getPendingRPC();
            Set<Map.Entry<String, NettyRpcFuture>> entrySet = pendingRPC.entrySet();
            for (Map.Entry<String, NettyRpcFuture> entry : entrySet) {
                NettyRpcFuture rpcFuture = entry.getValue();
                if(rpcFuture.isTimeout()){
                    String requestId = entry.getKey();
                    boolean removeFlag = removeNettyRPCFuture(requestId, rpcFuture);
                    if(removeFlag) {
//							rpcFuture.done(rpcResponse);
                    }
                }
            }
        }, 1, 1,TimeUnit.MINUTES);

    }

    private ConcurrentHashMap<String,NettyRpcFuture> getPendingRPC() {
        return pendingRPC;
    }
    @Override
    public void shutdown() throws Exception {
        ExecutorUtil.shutdownAndAwaitTermination(executorService, 60L, TimeUnit.MILLISECONDS);

    }

    public void addNettyRPCFuture(String requestId, NettyRpcFuture rpcFuture) {
        pendingRPC.put(requestId, rpcFuture);
    }

    public boolean removeNettyRPCFuture(String requestId, NettyRpcFuture rpcFuture) {
         return pendingRPC.remove(requestId, rpcFuture);
    }

    public NettyRpcFuture getNettyRPCFuture(String requestId) {
        return pendingRPC.get(requestId);
    }
}
