package net.northking.cctp.se.lifecycle;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.northking.cctp.common.http.ResultWrapper;
import net.northking.cctp.se.dto.EngineStatus;
import net.northking.cctp.se.dto.ScriptEngineInfo;
import net.northking.cctp.se.lifecycle.entity.ThreadPoolAllowDto;
import net.northking.cctp.se.thread.ExecutorPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

/**
 * 生命周期接口
 */
@RequestMapping(value = "/v1")
@RestController
@Api(tags = "生命周期接口")
public class LifecycleCtrl
{
  private static final Logger logger = LoggerFactory.getLogger(LifecycleCtrl.class);
  @Autowired
  private RestTemplate restTemplate;

  @Autowired
  private ObjectMapper objectMapper;

  @Autowired
  private RabbitTemplate rabbitTemplate;

  @Autowired
  private RedisTemplate redisTemplate;


  /**
   * 获取引擎运行信息
   *
   * @return 引擎运行信息
   */
  @ApiOperation(value = "获取引擎运行信息")
  @GetMapping(value = "/info")
  public ResultWrapper<ScriptEngineInfo> info()
  {
    ResultWrapper<ScriptEngineInfo> wrapper = new ResultWrapper<>();
    EngineRuntime engineRuntime = EngineRuntime.getRuntime();
    ScriptEngineInfo info = engineRuntime.getEngineInfo();
    wrapper.success(info);
    return wrapper;
  }

  /**
   * 获取redis指定Key的数据
   *
   * @return 引擎运行信息
   */
  @ApiOperation(value = "获取redis指定Key的数据")
  @GetMapping(value = "/getRedisKey/{key}")
  public ResultWrapper<Object> getRedisKey(@PathVariable("key") String key)
  {
    ResultWrapper<Object> wrapper = new ResultWrapper<>();
    Object info = redisTemplate.opsForValue().get(key);
    wrapper.success(info);
    return wrapper;
  }

  /**
   * 启用/禁用引擎
   *
   * @return 操作结果
   */
  @ApiOperation(value = "启用/禁用引擎")
  @PostMapping(value = "/manage",
      produces = MediaType.APPLICATION_JSON_VALUE,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  public ResultWrapper<Object> manage(ThreadPoolAllowDto target)
  {
    //直接修改三个线程的开关标识
    ResultWrapper<Object> wrapper = new ResultWrapper<>();
    EngineRuntime engineRuntime = EngineRuntime.getRuntime();
    ScriptEngineInfo info = engineRuntime.getEngineInfo();
    if(EngineStatus.STOPPING.equals(info.getStatus())){
      logger.info("引擎正在关闭中，无法操作线程启用禁用，请等待重启------");
      throw new RuntimeException("引擎正在关闭中，无法操作线程启用禁用，请等待重启------");
    }
    if (target.getInterfaceAllow()!=null) {
      ExecutorPool.enableApi = target.getInterfaceAllow();
    }
    if (target.getMobileAllow()!=null) {
      ExecutorPool.enableMobile = target.getMobileAllow();
    }
    if (target.getPcuiAllow()!=null) {
      ExecutorPool.enablePc = target.getPcuiAllow();
    }
    wrapper.success(true);
    return wrapper;
  }

  /**
   * 停止引擎
   *
   * @return 操作结果
   */
  @ApiOperation(value = "停止引擎")
  @PostMapping(value = "/stop",
      produces = MediaType.APPLICATION_JSON_VALUE,
      consumes = MediaType.APPLICATION_JSON_VALUE)
  public ResultWrapper<Object> stop(@RequestParam(required = false, value = "enforce", defaultValue = "false")boolean enforce)
  {
    //先关闭线程创建准许
    EngineRuntime engineRuntime = EngineRuntime.getRuntime();
    ScriptEngineInfo info = engineRuntime.getEngineInfo();
    ExecutorPool.stopAll();
    logger.info("停止引擎准备 任务创建允许关闭----------");
    StopServerThread stopThread = new StopServerThread(restTemplate,objectMapper,rabbitTemplate, enforce);
    stopThread.start();
    logger.info("停止引擎异步掉起 等待任务池情况，接口返回成功，并关闭----------");
    return new ResultWrapper<>().success();
  }
}
