package com.jiayue.ipfcst.dataexchange.controller;

import com.googlecode.aviator.AviatorEvaluator;
import com.jiayue.ipfcst.aop.SaveValidate;
import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
import com.jiayue.ipfcst.common.data.entity.ProtocolGatherDataPoint;
import com.jiayue.ipfcst.dataexchange.container.ProtocolDataContainer;
import com.jiayue.ipfcst.dataexchange.repository.ProtocolGatherDataPointRepository;
import com.jiayue.ipfcst.dataexchange.service.EquipmentAttributeService;
import com.jiayue.ipfcst.dataexchange.service.ProtocolGatherDataPointService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 协议点位的controller
 *
 * @author 修唯xiuwei
 * @version 3.0
 */
@Slf4j
@RestController
@RequestMapping("/dataExchange/protocolDataPoint")
public class ProtocolGatherDataPointController {

  private static final Pattern expr = Pattern.compile("(?<=P_).*?(?=_P)");

  private final ProtocolGatherDataPointService protocolGatherDataPointService;
  @Autowired
  EquipmentAttributeService equipmentAttributeService;
  @Autowired
  ProtocolGatherDataPointRepository protocolGatherDataPointRepository;

  /**
   * Protocol gather data point controller
   *
   * @param protocolGatherDataPointService protocol data point service
   */
  public ProtocolGatherDataPointController(ProtocolGatherDataPointService protocolGatherDataPointService) {
    this.protocolGatherDataPointService = protocolGatherDataPointService;
  }


  /**
   * 查询符合点位实体描述的点位
   *
   * @return ResponseVO gather data point
   */
  @GetMapping("/gatherDataPoint")
  public ResponseVO getGatherDataPoint(ProtocolGatherDataPoint protocolGatherDataPoint) {
    return ResponseVO.success(protocolGatherDataPointService.get(protocolGatherDataPoint));
  }


  /**
   * 查询通道下的点位
   *
   * @param tunnelId 通道id
   * @return ResponseVO 统一返回值
   */
  @GetMapping("/getByTunnelId/{tunnelId}")
  public ResponseVO getByTunnelId(@PathVariable("tunnelId") String tunnelId) {
    List<ProtocolGatherDataPoint> list = protocolGatherDataPointService.getByTunnelId(tunnelId);
    return ResponseVO.success(list);
  }

  /**
   * 根据通道和设备查询
   *
   * @param tunnelId
   * @param equipmentId
   * @param equipmentType
   * @return ResponseVO 统一返回值
   */
  @GetMapping("/getBytunnelAndEquipment/{tunnelId}/{equipmentId}/{equipmentType}")
  public ResponseVO getByTunnelAndEquipment(@PathVariable("tunnelId") String tunnelId, @PathVariable("equipmentId") String equipmentId, @PathVariable("equipmentType") Integer equipmentType) {
    try {
      List<ProtocolGatherDataPoint> list = protocolGatherDataPointService.getProtocolGatherDataPoint(tunnelId, equipmentId, equipmentType);
      return ResponseVO.success(list);
    } catch (Exception e) {
      e.printStackTrace();
      log.error("查询异常");
      return ResponseVO.fail();
    }
  }

  /**
   * 根据设备id和设备属性查询采集点表
   *
   * @param equipmentId          设备id
   * @param equipmentAttributeId 设备属性id
   * @return ResponseVO gather data point
   */
  @GetMapping("/getProtocolGatherDataPoint/{equipmentId}/{equipmentAttributeId}")
  public ResponseVO getProtocolGatherDataPoint(@PathVariable("equipmentId") Integer equipmentId, @PathVariable("equipmentAttributeId") Integer equipmentAttributeId) {
    try {
      List<ProtocolGatherDataPoint> list = this.protocolGatherDataPointService.getProtocolGatherDataPoint(equipmentId, equipmentAttributeId);
      return ResponseVO.success(list);
    } catch (Exception e) {
      e.printStackTrace();
      log.error("查询异常");
      return ResponseVO.fail();
    }
  }

  /**
   * 根据点表id查询点表
   *
   * @param id 设备id
   * @return ResponseVO gather data point
   */
  @GetMapping("/getDataPointById/{id}")
  public ResponseVO getDataPointById(@PathVariable("id") Integer id) {
    try {
      List<ProtocolGatherDataPoint> list = new ArrayList();
      ProtocolGatherDataPoint point = this.protocolGatherDataPointService.getDataPointById(id);
      list.add(point);
      return ResponseVO.success(list);
    } catch (Exception e) {
      e.printStackTrace();
      log.error("根据id查询采集点表异常");
      return ResponseVO.fail();
    }
  }

  /**
   * 储存采集点位
   *
   * @param protocolDataPoint 点位实体
   * @return ResponseVO response vo
   */
  @PostMapping("/saveDataPoint")
  @SaveValidate
  public ResponseVO saveGatherDataPoint(@RequestBody ProtocolGatherDataPoint protocolDataPoint) {
    return ResponseVO.success(protocolGatherDataPointService.save(protocolDataPoint));
  }


  /**
   * 校验公式 是否可以执行
   *
   * @param formula 所需要验证的公式
   * @return ResponseVO response vo
   */
  @GetMapping("/checkFormula")
  public ResponseVO checkFormula(String formula) {
    try {
      HashMap<String, Object> calculatingParameters = new HashMap<>();
      Matcher matcher = expr.matcher(formula);
      while (matcher.find()) {
        String s = matcher.group();
        if (ProtocolDataContainer.getInstance().isYxContains(Integer.parseInt(s))) {
          calculatingParameters.put("P_" + s + "_P", ProtocolDataContainer.getInstance().getBoolean(Integer.parseInt(s)));
          continue;
        } else if (ProtocolDataContainer.getInstance().isYcContains(Integer.parseInt(s))) {
          calculatingParameters.put("P_" + s + "_P", ProtocolDataContainer.getInstance().getNumber(Integer.parseInt(s)));
          continue;
        } else {
         return ResponseVO.fail(null,"当前数据池无"+"P_" + s + "_P"+"点位，请根据已有点位进行公式生成");
        }
      }
      Object o = AviatorEvaluator.compile(formula).execute(calculatingParameters);
      if (o == null) {
        return ResponseVO.fail();
      }
      return ResponseVO.success();
    } catch (Exception e) {
      e.printStackTrace();
      return ResponseVO.fail();
    }
  }


  /**
   * 修改采集点表
   *
   * @param protocolDataPoint 点位实体
   * @return ResponseVO response vo
   */
  @PutMapping("/updateDataPoint")
  @SaveValidate
  public ResponseVO updateGatherDataPoint(@RequestBody ProtocolGatherDataPoint protocolDataPoint) {
    return ResponseVO.success(protocolGatherDataPointService.save(protocolDataPoint));
  }

  /**
   * 删除采集点表
   *
   * @param id 点位Id
   */
  @DeleteMapping("/deleteById/{id}")
  @SaveValidate
  public ResponseVO deleteById(@PathVariable("id") Integer id) {
    try {
      protocolGatherDataPointService.deleteById(id);
      return ResponseVO.success(1);
    } catch (Exception e) {
      e.printStackTrace();
      log.error("删除异常");
      return ResponseVO.fail();
    }
  }

  @DeleteMapping("/batchDeleteGatherDataPoint/{pointIds}")
  @SaveValidate
  public ResponseVO batchDeleteGatherDataPoint(@PathVariable Integer[] pointIds) {
    try {
      for (int i = 0; i < pointIds.length; i++) {
        ProtocolGatherDataPoint point = new ProtocolGatherDataPoint();
        point.setId(pointIds[i]);
        protocolGatherDataPointService.deleteAll(point);
      }
      return ResponseVO.success(1);
    } catch (Exception e) {
      e.printStackTrace();
      log.error("批量删除异常");
      return ResponseVO.fail(e);
    }
  }
}
