package net.northking.cctp.se.debugger.pool;

import net.northking.cctp.se.debugger.InterfaceDebugger;
import net.northking.cctp.se.dto.ATUWebSocketReplay;
import net.northking.cctp.se.thread.ExecutorPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.CloseReason;
import javax.websocket.Session;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import static javax.websocket.CloseReason.CloseCodes.CANNOT_ACCEPT;

public class WebSocketInterfaceDebuggerPool implements WebSocketDebuggerPool
{
  public static final Logger logger = LoggerFactory.getLogger(WebSocketInterfaceDebuggerPool.class);

  private static WebSocketInterfaceDebuggerPool instance = new WebSocketInterfaceDebuggerPool();

  private WebSocketInterfaceDebuggerPool()
  {
  }

  public static WebSocketInterfaceDebuggerPool getInstance()
  {
    return instance;
  }

  /**
   * 最大在线客户端数量
   */
  private static final int MAX_ONLINE_CLIENT = 10;


  // 接口自动化线程池
  private ExecutorService executorService = new ThreadPoolExecutor(0, MAX_ONLINE_CLIENT,
          0L, TimeUnit.MILLISECONDS,
          new LinkedBlockingQueue<Runnable>());
  private Map<String,InterfaceDebugger> debuggerMap = new HashMap<>();


  @Override
  public void createDebugger(Session session, String deviceToken)
  {
    //校验接口自动化线程是否开启创建
    if(!ExecutorPool.enableApi){
      try {
        session.close(new CloseReason(CANNOT_ACCEPT, "接口自动化引擎连接已禁用，拒绝连接"));
      } catch (IOException e) {
        logger.error("拒绝创建调试器。关闭会话失败！", e);
      }
    }
    if(MAX_ONLINE_CLIENT>=debuggerMap.size()){
      InterfaceDebugger debugger = new InterfaceDebugger(deviceToken, session);
      executorService.submit(debugger);
      debuggerMap.put(deviceToken,debugger);
    }else
    {// 拒绝创建【接口自动化测试调试器】
      try
      {
        session.close(new CloseReason(CANNOT_ACCEPT, "接口自动化引擎连接已到最大值，拒绝连接"));
      } catch (IOException e)
      {
        logger.error("拒绝创建调试器。关闭会话失败！", e);
      }
    }
  }

  @Override
  public void destroyDebugger(String deviceToken)
  {
    if(debuggerMap.containsKey(deviceToken)){
      InterfaceDebugger debugger = debuggerMap.get(deviceToken);
      debugger.close();
      debuggerMap.remove(deviceToken);
    }
  }

  @Override
  public void replayStart(String deviceToken, ATUWebSocketReplay replayRequest)
  {
    if(debuggerMap.containsKey(deviceToken)){
      InterfaceDebugger debugger = debuggerMap.get(deviceToken);
      if (debugger.isStopped())
      {
        debugger.replay(replayRequest);
        Thread debuggerThread = new Thread(debugger);
        debuggerThread.setDaemon(true);
        debuggerThread.start();
      }
    }

  }

  @Override
  public void replayStop(String deviceToken)
  {
    if(debuggerMap.containsKey(deviceToken)){
      InterfaceDebugger debugger = debuggerMap.get(deviceToken);
      debugger.stop();
    }
  }

  /**
   * 访问线程池
   * @return
   */
  public Map<String,InterfaceDebugger> getPoolInfo(){
    return debuggerMap;
  }
}
