/*
* Copyright (c) 京北方信息技术股份有限公司 Corporation 2022 . All rights reserved.
*
*/
package net.northking.cctp.device.api.ctrl.service;

import net.northking.cctp.common.db.BasicService;
import net.northking.cctp.common.db.Pagination;
import net.northking.cctp.common.db.annotation.DatabaseReadOnly;
import net.northking.cctp.common.db.annotation.DatabaseWriteOnly;
import net.northking.cctp.common.db.excel.AbstractExcelService;
import net.northking.cctp.common.db.excel.ExcelHeader;
import net.northking.cctp.common.http.QueryByPage;
import net.northking.cctp.common.util.UUIDUtil;

import net.northking.cctp.device.bus.publisher.CtrlMQPublisher;
import net.northking.cctp.device.constants.DeviceConstants;
import net.northking.cctp.device.db.service.CdDeviceCtrlService;
import net.northking.cctp.device.db.entity.CdDeviceCtrl;

import net.northking.cctp.device.dto.ctrl.CdDeviceCtrlAddDto;
import net.northking.cctp.device.dto.ctrl.CdDeviceCtrlDetailDto;
import net.northking.cctp.device.dto.ctrl.CdDeviceCtrlQueryDto;
import net.northking.cctp.device.dto.ctrl.CdDeviceCtrlUpdateDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 上位机管理表服务实现类
 *
 * @author maven-cctp-plugin
 * @since 1.0
 */

@Service
@ConditionalOnMissingBean(name = "CdDeviceCtrlApiServiceImpl")
public class CdDeviceCtrlApiServiceImpl extends AbstractExcelService<CdDeviceCtrl> implements CdDeviceCtrlApiService
{
  /**
   * 日志
   */
  private final static Logger logger = LoggerFactory.getLogger(CdDeviceCtrlApiServiceImpl.class);

  @Autowired
  private CdDeviceCtrlService cdDeviceCtrlService;

  @Autowired
  private CtrlMQPublisher ctrlMQPublisher;

  //= Excel 导入导出相关代码 start ==================//
  @Override
  public BasicService<CdDeviceCtrl> getService()
  {
    return this.cdDeviceCtrlService;
  }

  @Override
  public ExcelHeader[] excelHeaders()
  {
    ExcelHeader id = new ExcelHeader("主键id", "id", String.class);
    ExcelHeader ctrlName = new ExcelHeader("上位机名称", "ctrlName", String.class);
    ExcelHeader ctrlIp = new ExcelHeader("上位机ip", "ctrlIp", String.class);
    ExcelHeader ctrlAddr = new ExcelHeader("上位机位置", "ctrlAddr", String.class);
    ExcelHeader ctrlStatus = new ExcelHeader("上位机状态", "ctrlStatus", String.class);
    ExcelHeader ctrlUpLimit = new ExcelHeader("接入设备上限", "ctrlUpLimit", Integer.class);
    ExcelHeader remark = new ExcelHeader("备注", "remark", String.class);
    ExcelHeader createdTime = new ExcelHeader("注册时间", "createdTime", Date.class);
    ExcelHeader updatedBy = new ExcelHeader("更新人", "updatedBy", String.class);
    ExcelHeader updatedTime = new ExcelHeader("更新时间", "updatedTime", Date.class);
    return new ExcelHeader[]{};
  }

  /**
   * Excel导入，入库之前的处理
   * @param records 从Excel读取到的记录
   * @return 待入库的记录
   */
  @Override
  protected List<CdDeviceCtrl> beforeInsertBatch(List<CdDeviceCtrl> records)
  {
    for (CdDeviceCtrl record : records)
    {
      record.setId(UUIDUtil.create32UUID());
    }
    return records;
  }

  /**
   * 写入Excel之前的处理<br>
   * 数据的特殊处理在此处加工处理
   *
   * @param record 来自数据库记录
   * @return 待写入Excel的记录
   */
  @Override
  protected CdDeviceCtrl beforeWriteExcel(CdDeviceCtrl record)
  {
    return record;
  }

  //= Excel 导入导出相关代码 end =======================//

  //= 增删改查 相关代码 start ==================//
  @Override
  @DatabaseReadOnly
  public Pagination<CdDeviceCtrlDetailDto> pagingQuery(QueryByPage<CdDeviceCtrlQueryDto> queryByPage)
  {
    return this.cdDeviceCtrlService.pagingQuery(queryByPage);
  }

  @Override
  @DatabaseWriteOnly
  public String add(CdDeviceCtrlAddDto dto)
  {
    CdDeviceCtrl entity = new CdDeviceCtrl();
    BeanUtils.copyProperties(dto, entity);

    CdDeviceCtrl ctrl = new CdDeviceCtrl();
    ctrl.setCtrlIp(dto.getCtrlIp());
    List<CdDeviceCtrl> query = this.cdDeviceCtrlService.query(ctrl);
    if (query.size()>0){
      query.get(0).setCtrlStatus(DeviceConstants.CTRL_STATUS_ONLINE);
      this.cdDeviceCtrlService.updateByPrimaryKey(query.get(0));
    }else{
      String uuid = UUIDUtil.create32UUID();
      entity.setId(uuid);
      entity.setCtrlStatus(DeviceConstants.CTRL_STATUS_ONLINE);
      this.cdDeviceCtrlService.insert(entity);
    }
    return DeviceConstants.CTRL_REGISTER_SUCCESS;
  }

  @Override
  @DatabaseWriteOnly
  public Integer updateByPK(CdDeviceCtrlUpdateDto dto) throws IllegalAccessException
  {
    CdDeviceCtrl entity = new CdDeviceCtrl();
    BeanUtils.copyProperties(dto, entity);
    return this.cdDeviceCtrlService.updateByPrimaryKey(entity);
  }

  @Override
  @DatabaseReadOnly
  public CdDeviceCtrlDetailDto findByPK(String uuid)
  {
    CdDeviceCtrl example = new CdDeviceCtrl();
    example.setId(uuid);
    List<CdDeviceCtrl> entitys = this.cdDeviceCtrlService.query(example);
    if (entitys.isEmpty())
    {
      return null;
    }

    CdDeviceCtrlDetailDto dto = new CdDeviceCtrlDetailDto();
    BeanUtils.copyProperties(entitys.get(0), dto);
    return dto;
  }

  @Override
  @DatabaseWriteOnly
  public Integer deleteByPK(String uuid)
  {
    CdDeviceCtrl entity = new CdDeviceCtrl();
    entity.setId(uuid);
    entity.setCtrlStatus(DeviceConstants.CTRL_STATUS_DEL);
    return this.cdDeviceCtrlService.updateByPrimaryKey(entity);
  }

  @Override
  public List<String> addBatch(List<CdDeviceCtrlAddDto> batch)
  {
    List<String> result = new ArrayList<>();
    for (CdDeviceCtrlAddDto dto : batch)
    {
      result.add(this.add(dto));
    }
    return result;
  }

  @Override
  public Integer updateBatch(List<CdDeviceCtrlUpdateDto> batch) throws IllegalAccessException
  {
    int sum = 0;
    for (CdDeviceCtrlUpdateDto dto : batch)
    {
      sum = sum + this.updateByPK(dto);
    }
    return sum;
  }

  @Override
  public Integer deleteBatch(List<Object> batch)
  {
    return this.cdDeviceCtrlService.deleteByPrimaryKeys(batch);
  }

  @Override
  public String restartCtrl(String id) {
    CdDeviceCtrl ctrl = this.cdDeviceCtrlService.findByPrimaryKey(id);
    String result = DeviceConstants.CTRL_RESTART_MSG;
    if (!ctrl.getCtrlStatus().equals(DeviceConstants.CTRL_STATUS_OFFLINE)) {
      ctrlMQPublisher.restartCtrl(id);
      logger.info("上位机【{}】正在重启",ctrl.getCtrlIp());
    }
    return result;
  }

  @Override
  public String registerCtrl(CdDeviceCtrl ctrl) {
    //上位机注册
    CdDeviceCtrl dto = new CdDeviceCtrl();
    dto.setId(ctrl.getId());
    dto.setCtrlIp(ctrl.getCtrlIp());
    List<CdDeviceCtrl> query = this.cdDeviceCtrlService.query(dto);
    if (query.size()>0) {
      //修改上位机信息
      this.cdDeviceCtrlService.updateByPrimaryKey(ctrl);
    }else {
      CdDeviceCtrl deviceCtrl = this.cdDeviceCtrlService.findByPrimaryKey(ctrl.getId());
      if (deviceCtrl!=null){
        //上位机修改ip的情况
        this.cdDeviceCtrlService.updateByPrimaryKey(ctrl);
      }else {
        //新增上位机
        ctrl.setCreatedTime(new Date());
        this.cdDeviceCtrlService.insert(ctrl);
      }
    }
    return DeviceConstants.DEVICE_REGISTER_SUCCESS;
  }

}
