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

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.util.StringUtil;
import com.hzbank.testteam.autotest.dependencies.authDependency.entity.Project;
import com.hzbank.testteam.autotest.dependencies.authDependency.utils.RequestUtil;
import com.hzbank.testteam.autotest.dependencies.monsterDependency.dto.UserDTO;
import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.cache.EntityNameCatalog;
import net.northking.cctp.common.db.BasicService;
import net.northking.cctp.common.db.DefaultPagination;
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.dto.AdvancedQueryOptions;
import net.northking.cctp.common.dto.CpLogAddDto;
import net.northking.cctp.common.dto.UserOptions;
import net.northking.cctp.common.enums.FileBusinessTypeEnum;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.feign.MonsterCommonFeignClient;
import net.northking.cctp.common.feign.MonsterLogServer;
import net.northking.cctp.common.http.QueryByPage;
import net.northking.cctp.common.http.ResultWrapper;
import net.northking.cctp.common.security.authentication.NKSecurityContext;
import net.northking.cctp.common.util.DateUtil;
import net.northking.cctp.common.util.UUIDUtil;
import net.northking.cctp.scriptcase.api.scenescript.service.coordinate.SceneCoordinatorService;
import net.northking.cctp.scriptcase.constants.ScriptConstant;
import net.northking.cctp.scriptcase.db.entity.AtuCaseDataSet;
import net.northking.cctp.scriptcase.db.entity.AtuInputSet;
import net.northking.cctp.scriptcase.db.entity.AtuScriptGroup;
import net.northking.cctp.scriptcase.db.entity.AtuScriptInfo;
import net.northking.cctp.scriptcase.db.service.*;
import net.northking.cctp.scriptcase.dto.IdAndStatusDto;
import net.northking.cctp.scriptcase.dto.atuScript.UserQueryDto;
import net.northking.cctp.scriptcase.dto.atuScript.atuScriptInfo.PrincipalUpdateDto;
import net.northking.cctp.scriptcase.dto.caseDataSet.*;
import net.northking.cctp.scriptcase.enums.ScriptCaseAppError;
import net.northking.cctp.scriptcase.feign.AttachmentFeignClient;
import net.northking.cctp.scriptcase.feign.ExecutePlanFeignClient;
import net.northking.cctp.scriptcase.feign.PlatformFeignClient;
import org.apache.commons.lang.StringUtils;
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.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

import static net.northking.cctp.scriptcase.enums.ScriptCaseAppError.PROJECT_ID_NOT_EXIST;

/**
 * 用例集目录表服务实现类
 *
 * @author maven-cctp-plugin
 * @since 1.0
 */

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

  private final static String commonKey = "UITEST-case.set.common";

  private final static String sceneKey = "UITEST-case.set.scene";

  @Autowired
  private AtuCaseDataSetService atuCaseDataSetService;

  @Autowired
  private AtuScriptGroupService atuScriptGroupService;

  @Autowired
  private AtuScriptInfoService atuScriptInfoService;

  @Autowired
  private RedisTemplate redisTemplate;

  @Autowired
  private ExecutePlanFeignClient executePlanFeignClient;

  @Autowired
  private EntityNameCache entityNameCache;
  @Autowired
  private PlatformFeignClient platformFeignClient;

  @Autowired
  private SceneCoordinatorService sceneCoordinatorService;

  @Autowired
  private AppService appService;

  @Autowired
  private AtuSceneNodeInfoService sceneNodeInfoService;

  @Autowired
  private AtuInputSetService atuInputSetService;

  @Autowired
  MonsterCommonFeignClient monsterCommonFeignClient;

  @Autowired
  private AttachmentFeignClient attachmentFeignClient;

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

  @Override
  public ExcelHeader[] excelHeaders()
  {
    ExcelHeader id = new ExcelHeader("主键", "id", String.class);
    ExcelHeader setName = new ExcelHeader("目录名称", "setName", String.class);
    ExcelHeader projectId = new ExcelHeader("系统id", "projectId", String.class);
    ExcelHeader scriptId = new ExcelHeader("脚本id", "scriptId", String.class);
    ExcelHeader path = new ExcelHeader("路径", "path", String.class);
    ExcelHeader leaf = new ExcelHeader("是否叶子节点", "leaf", Boolean.class);
    ExcelHeader parentId = new ExcelHeader("父节点", "parentId", String.class);
    ExcelHeader createdBy = new ExcelHeader("创建人", "createdBy", String.class);
    ExcelHeader createdTime = new ExcelHeader("创建时间", "createdTime", Date.class);
    ExcelHeader updatedBy = new ExcelHeader("更新人", "updatedBy", String.class);
    ExcelHeader updatedTime = new ExcelHeader("更新时间", "updatedTime", Date.class);
    ExcelHeader tenantId = new ExcelHeader("租户id", "tenantId", String.class);
    return new ExcelHeader[]{};
  }

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

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

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

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

  @Override
  @DatabaseWriteOnly
  public String add(AtuCaseDataSetAddDto dto)
  {
    String uuid = UUIDUtil.create32UUID();
    AtuCaseDataSet entity = new AtuCaseDataSet();
    BeanUtils.copyProperties(dto, entity);
    entity.setId(uuid);
    this.atuCaseDataSetService.insert(entity);
    return uuid;
  }

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

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

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

  @Override
  @DatabaseWriteOnly
  public Integer deleteByPK(String uuid)
  {
    AtuCaseDataSet entity = new AtuCaseDataSet();
    entity.setId(uuid);
    return this.atuCaseDataSetService.deleteByExample(entity);
  }

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

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

  @Override
  public Integer deleteBatch(List<Object> batch) {
    // 查询用例集对应的脚本id集合
    List<String> scriptIdList = this.atuCaseDataSetService.queryScriptIdBySetIdList(batch);
    if (scriptIdList != null && scriptIdList.size() > 0) {
      // 校验是否被计划使用
      Boolean flag = executePlanFeignClient.checkDataSetUsedByScriptIdList(scriptIdList);
      if (flag) {//true:存在关联，删除失败  false:不存在关联
        throw new PlatformRuntimeException(ScriptCaseAppError.CASE_DATA_SET_HAS_PLAN);
      }
      //找出用例集对应的输入项
      List<AtuInputSet> inputSetList = new ArrayList<>();
      for (String scriptId : scriptIdList) {
        AtuInputSet inputSet = new AtuInputSet();
        inputSet.setScriptId(scriptId);
        List<AtuInputSet> query = this.atuInputSetService.query(inputSet);
        if (query.size() > 0) {
          inputSetList.addAll(query);
        }
      }
      if (inputSetList.size()>0) {
        //删除输入项
        inputSetList.forEach(item -> {
          attachmentFeignClient.deleteFileByObjId(item.getScriptId(), FileBusinessTypeEnum.INPUT_DATA_SET.getCode());
        });
        List<Object> inputSetIds = inputSetList.stream().map(AtuInputSet::getId).collect(Collectors.toList());
        this.atuInputSetService.deleteByPrimaryKeys(inputSetIds);
      }
    }
    Project project = RequestUtil.getProject();
    String content = "";
    if (batch.size() > 1) {
      content = "【批量删除用例集】系统:" + project.getName() +"，共"+batch.size() + "条";
    } else {
      AtuCaseDataSet byPrimaryKey = this.atuCaseDataSetService.findByPrimaryKey(batch.get(0));
      content = "【删除用例集】系统:" + project.getName() +"，用例集名称：" + byPrimaryKey.getSetName();
    }
    CpLogAddDto logAddDto=new CpLogAddDto();
    logAddDto.setType("3");//删除
    logAddDto.setContent(content);
    logAddDto.setModule("用例集管理");
    MonsterLogServer.sendLogToMonster(logAddDto);
    //删除用例集
    return this.atuCaseDataSetService.deleteByPrimaryKeys(batch);
  }

  @Override
  public List<AtuCaseDataSetMenuDto> querySetTree(AtuSetTreeQueryDto dto) {
    List<AtuCaseDataSetMenuDto> result = new ArrayList<>();
    if (dto.isProFlag()) {
      //多系统
      //查询条件不为空
      if (!StringUtils.isBlank(dto.getSetName())) {
        for (String proId : dto.getProId()) {
          String proName = entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM, proId);
          if (proName.contains(dto.getSetName())) {
            //查询系统下的脚本
            AtuCaseDataSet proChild = new AtuCaseDataSet();
            proChild.setProjectId(proId);
            //组装节点
            AtuCaseDataSetMenuDto proNode = new AtuCaseDataSetMenuDto();
            proNode.setSetName(proName);
            proNode.setProjectId(proId);
            proNode.setChildNode(queryTreeByPro(proChild));
            result.add(proNode);
          } else {
            //查询系统下是否存在符合条件的脚本
            AtuCaseDataSet proChild = new AtuCaseDataSet();
            proChild.setProjectId(proId);
            proChild.setSetName(dto.getSetName());
            List<AtuCaseDataSetMenuDto> resultDto = queryTreeByProAndName(proChild);
            //如果无数据 不展示这个系统节点
            if (resultDto.size() > 0) {
              AtuCaseDataSetMenuDto proNode = new AtuCaseDataSetMenuDto();
              proNode.setSetName(proName);
              proNode.setProjectId(proId);
              proNode.setChildNode(resultDto);
              result.add(proNode);
            }
          }
        }
      } else {
        //展示所有系统的情况
        for (String proId : dto.getProId()) {
          String proName = entityNameCache.translateById(EntityNameCatalog.MONSTER_SYSTEM, proId);
          //查询系统下的脚本
          AtuCaseDataSet proChild = new AtuCaseDataSet();
          proChild.setProjectId(proId);
          //组装节点
          AtuCaseDataSetMenuDto proNode = new AtuCaseDataSetMenuDto();
          proNode.setSetName(proName);
          proNode.setProjectId(proId);
          proNode.setChildNode(queryTreeByPro(proChild));
          result.add(proNode);
        }
      }
    } else {
      //单系统
      // 查询所有
      AtuCaseDataSet queryDto = new AtuCaseDataSet();
      queryDto.setProjectId(dto.getProId().get(0));
      queryDto.setSetName(dto.getSetName());
      // 封装树结构
      result = queryTreeByPro(queryDto);
    }
    return result;
  }

  @Override
  public List<AtuCaseDataSetMenuDto> picusQuerySetTree(PicusQueryDto dto) {
    if (StringUtils.isBlank(dto.getProId())){
      throw new PlatformRuntimeException(PROJECT_ID_NOT_EXIST);
    }
    AtuCaseDataSet queryDto = new AtuCaseDataSet();
    queryDto.setProjectId(dto.getProId());
    return queryTreeByPro(queryDto);
  }

  @Override
  public List<IdAndStatusDto> picusQueryByScriptIds(List<String> ids) {
    return atuCaseDataSetService.picusQueryByScriptIds(ids);
  }

  @Override
  public List<AtuCaseDataSetMenuDto> queryPlanSetTree(AtuCaseDataSetFeignDto dto) {
    AtuCaseDataSet queryDto = new AtuCaseDataSet();
    queryDto.setProjectId(dto.getProId());
    return queryTreeByPro(queryDto);
  }

  @Override
  public void saveScriptSetTree(SetTreeDto dto) {
    List<AtuCaseDataSet> list = new ArrayList<>();
    //一般用例集
    AtuScriptInfo scriptInfo = this.atuScriptInfoService.findByPrimaryKey(dto.getId());
    AtuScriptGroup scriptGroup = this.atuScriptGroupService.findByPrimaryKey(scriptInfo.getGroupId());
    String[] split = scriptGroup.getIdPath().split("/");
    List<String> ids = Arrays.asList(split);
    List<AtuScriptGroup> scriptGroups = this.atuScriptGroupService.queryByIds(ids);

    AtuCaseDataSet commonNode = getCommonNode();
    //同步新增树目录
    for (AtuScriptGroup group : scriptGroups) {
      AtuCaseDataSet dataSet = new AtuCaseDataSet();
      dataSet.setId(group.getId());
      dataSet.setScriptId(scriptInfo.getId());
      dataSet.setSetName(group.getGroupName());
      dataSet.setProjectId(group.getProjectId());
      dataSet.setPath(commonNode.getPath() + "/" + group.getIdPath());
      dataSet.setLeaf(false);
      dataSet.setLevelNo(group.getLevelNo() + 1);
      dataSet.setIdx(Integer.valueOf(group.getSeq()));
      dataSet.setCreatedBy(NKSecurityContext.getUserId());
      dataSet.setCreatedTime(new Date());
      if (group.getPid().equals(ScriptConstant.STR_ZERO)) {
        dataSet.setParentId(commonNode.getId());
      } else {
        dataSet.setParentId(group.getPid());
      }
      dataSet.setTenantId(NKSecurityContext.getTenantId());
      list.add(dataSet);
    }
    //叶子节点
    AtuCaseDataSet scriptNode = new AtuCaseDataSet();
    scriptNode.setId(dto.getId());
    scriptNode.setScriptId(scriptInfo.getId());
    scriptNode.setSetName(scriptInfo.getScriptName());
    scriptNode.setProjectId(scriptInfo.getProjectId());
    scriptNode.setPath(commonNode.getPath() + "/" + scriptGroup.getIdPath() + "/" + dto.getId());
    scriptNode.setLeaf(true);
    scriptNode.setScriptType(dto.getScriptType());
    scriptNode.setPrincipalId(NKSecurityContext.getUserId());
    scriptNode.setLevelNo(scriptGroup.getLevelNo() + 2);
    scriptNode.setUpdatedBy(NKSecurityContext.getUserId());
    scriptNode.setUpdatedTime(new Date());
    if (!StringUtil.isEmpty(dto.getVersion())) {
      scriptNode.setVersion(dto.getVersion());
    }
    AtuCaseDataSet queryChildIdx = new AtuCaseDataSet();
    queryChildIdx.setParentId(scriptGroup.getId());
    List<AtuCaseDataSet> query = this.atuCaseDataSetService.query(queryChildIdx);
    if (query.size() > 0) {
      scriptNode.setIdx(query.size() + 1);
    } else {
      scriptNode.setIdx(1);
    }
    scriptNode.setParentId(scriptGroup.getId());
    scriptNode.setTenantId(NKSecurityContext.getTenantId());
    scriptNode.setCreatedBy(NKSecurityContext.getUserId());
    scriptNode.setCreatedTime(new Date());
    if (dto.getUpdateTime() != null) {
      scriptNode.setUpdatedTime(dto.getUpdateTime());
    }
    if (!StringUtils.isEmpty(dto.getUpdateBy())) {
      scriptNode.setUpdatedBy(dto.getUpdateBy());
    }
    list.add(scriptNode);
    this.atuCaseDataSetService.replaceTreeSet(list);
  }

  @Override
  public void saveSceneSetTree(SetTreeDto dto) {
    List<AtuCaseDataSet> list = new ArrayList<>();
    //场景用例集
    AtuCaseDataSet sceneNode = getSceneNode();
    //叶子节点
    AtuCaseDataSet sceneScript = new AtuCaseDataSet();
    //查询排序
    sceneScript.setParentId(sceneNode.getId());
    sceneScript.setTenantId(NKSecurityContext.getTenantId());
    sceneScript.setProjectId(dto.getProjectId());
    List<AtuCaseDataSet> query = this.atuCaseDataSetService.query(sceneNode);
    if (query.size() > 0) {
      sceneScript.setIdx(query.size() + 1);
    } else {
      sceneScript.setIdx(1);
    }
    sceneScript.setId(dto.getId());
    sceneScript.setScriptId(dto.getId());
    sceneScript.setLevelNo(2);
    sceneScript.setSetName(dto.getScriptName());
    sceneScript.setPath(sceneNode.getPath() + "/" + dto.getId());
    sceneScript.setLeaf(true);
    sceneScript.setCreatedBy(NKSecurityContext.getUserId());
    sceneScript.setCreatedTime(new Date());
    sceneScript.setUpdatedBy(NKSecurityContext.getUserId());
    sceneScript.setUpdatedTime(new Date());
    sceneScript.setScriptType(dto.getScriptType());
    sceneScript.setVersion(dto.getVersion());
    sceneScript.setPrincipalId(NKSecurityContext.getUserId());
    if (dto.getUpdateTime() != null) {
      sceneScript.setUpdatedTime(dto.getUpdateTime());
    }
    if (!StringUtils.isEmpty(dto.getUpdateBy())) {
      sceneScript.setUpdatedBy(dto.getUpdateBy());
    }
    list.add(sceneScript);
    this.atuCaseDataSetService.replaceTreeSet(list);
  }



  @Override
  public Pagination<AtuCaseScriptResultDto> queryScriptByPath(QueryByPage<AtuCaseScriptQueryDto> dto) {
    Pagination<AtuCaseScriptResultDto> result = new DefaultPagination<>();
    if ("0".equals(dto.getQuery().getNodeId())) {
      dto.getQuery().setNodeId(null);
    }
    buildDto(dto);
    dto.getQuery().setTenantId(NKSecurityContext.getTenantId());
    if ("5".equals(dto.getQuery().getScriptType())) {
        result = this.atuCaseDataSetService.querySceneNode(dto);
    }
    if (StringUtils.isEmpty(dto.getQuery().getScriptType())) {
      result = this.atuCaseDataSetService.queryCommonNodeAndSceneNode(dto);
    }
    if (!StringUtils.isEmpty(dto.getQuery().getScriptType())
            && !StringUtils.equals("5",dto.getQuery().getScriptType())) {
      result = this.atuCaseDataSetService.queryCommonNode(dto);
    }
    if (result.getRecords() != null && result.getRecords().size() > 0) {
      result.getRecords().forEach(one -> {
        String updatedName = entityNameCache.translateById(EntityNameCatalog.MONSTER_USER, one.getUpdatedBy());
        String createdName = entityNameCache.translateById(EntityNameCatalog.MONSTER_USER, one.getCreatedBy());
        String principalName = entityNameCache.translateById(EntityNameCatalog.MONSTER_USER, one.getPrincipalId());
        one.setPrincipalName(principalName);
        one.setUpdatedName(updatedName);
        one.setCreatedName(createdName);
      });
    }
    return result;
  }

  private void buildDto(QueryByPage<AtuCaseScriptQueryDto> dto) {
    AtuCaseScriptQueryDto query = dto.getQuery();
    if (!StringUtils.isEmpty(query.getPrincipal())) {
      List<String> principalIds = getUserIds(query.getPrincipal());
      if (!CollectionUtil.isEmpty(principalIds)) {
        query.setPrincipalIds(principalIds);
      } else {
        principalIds.add(ScriptConstant.STR_MINUS_ONE);
        query.setPrincipalIds(principalIds);
      }
    }
    if (!StringUtils.isEmpty(query.getUpdatedName())) {
      List<String> updateBys = getUserIds(query.getUpdatedName());
      if (!CollectionUtils.isEmpty(updateBys)) {
        query.setUpdatedBys(updateBys);
      } else {
        updateBys.add(ScriptConstant.STR_MINUS_ONE);
        query.setUpdatedBys(updateBys);
      }
    }
    if (!StringUtils.isEmpty(query.getCreator())) {
      List<String> createBys = getUserIds(query.getCreator());
      if (!CollectionUtils.isEmpty(createBys)) {
        query.setCreateBys(createBys);
      } else {
        createBys.add(ScriptConstant.STR_MINUS_ONE);
        query.setCreateBys(createBys);
      }
    }
    //创建时间--时间区间  修改时间--时间区间
    String createdTimeStart = query.getCreatedTimeStart();
    if (!StringUtils.isEmpty(createdTimeStart)) {
      Date startCreatedTime = null;
      try {
        startCreatedTime = DateUtil.parse(createdTimeStart + ScriptConstant.BEGIN_TIME,ScriptConstant.TIME_PATTERN);

      } catch (ParseException e) {
        logger.error("时间转换异常，createdTimeStart，{}，e,{}",createdTimeStart,e.getMessage());
        throw new PlatformRuntimeException(ScriptCaseAppError.PARSE_DATE_ERROR);
      }
      query.setStartCreatedTime(startCreatedTime);
    }
    String createdTimeEnd = query.getCreatedTimeEnd();
    if (!StringUtils.isEmpty(createdTimeEnd)) {
      Date endCreatedTime = null;
      try {
        endCreatedTime = DateUtil.parse(createdTimeEnd+ ScriptConstant.END_TIME,ScriptConstant.TIME_PATTERN);

      } catch (ParseException e){
        logger.error("时间转换异常，createdTimeEnd，{}，e,{}",createdTimeEnd,e.getMessage());
        throw new PlatformRuntimeException(ScriptCaseAppError.PARSE_DATE_ERROR);
      }
      query.setEndCreatedTime(endCreatedTime);
    }
    // 更新时间
    String updatedTimeStart = query.getUpdatedTimeStart();
    if (!StringUtils.isEmpty(updatedTimeStart)) {
      Date startUpdatedTime = null;
      try{
        startUpdatedTime = DateUtil.parse(updatedTimeStart+ScriptConstant.BEGIN_TIME,ScriptConstant.TIME_PATTERN);
      }catch (ParseException e){
        logger.error("时间转换异常，updatedTimeStart，{}，e,{}",updatedTimeStart,e.getMessage());
        throw new PlatformRuntimeException(ScriptCaseAppError.PARSE_DATE_ERROR);
      }
      query.setStartUpdatedTime(startUpdatedTime);
    }
    String updatedTimeEnd = query.getUpdatedTimeEnd();
    if (!StringUtils.isEmpty(updatedTimeEnd)) {
      Date endUpdatedTime = null;
      try {
        endUpdatedTime = DateUtil.parse(updatedTimeEnd+ ScriptConstant.END_TIME,ScriptConstant.TIME_PATTERN);
      } catch (ParseException e) {
        logger.error("时间转换异常，updatedTimeEnd，{}，e,{}",updatedTimeEnd,e.getMessage());
        throw new PlatformRuntimeException(ScriptCaseAppError.PARSE_DATE_ERROR);
      }
      query.setEndUpdatedTime(endUpdatedTime);
    }
  }

  /**
   * 查询人名可带正则表达式
   * @param userName
   * @return
   */
  private List<String> getUserIds(String userName) {
    UserQueryDto example = new UserQueryDto();
    if(userName.contains(",")||userName.contains("，")){
      userName = userName.replace(",","|")
              .replace("，","|")
              .replace("(","\\(")
              .replace(")","\\)");
      example.setUserChnNames(userName);
    }else{
      example.setUserChnName(userName);
    }
    example.setTenantId(NKSecurityContext.getTenantId());
    List<String> userIds = platformFeignClient.selectUserId(example);
    if (userIds == null) {
      userIds = new ArrayList<>();
    }
    return userIds;
  }

  @Override
  public Integer updatePrincipal(PrincipalUpdateDto dto) {
    if (dto.getScriptList().size() == 0){
      return 0;
    }
    Long requestUserId = RequestUtil.getRequestUserId();
    dto.setUpdatedBy(String.valueOf(requestUserId));
    dto.setUpdatedTime(new Date());
    return this.atuCaseDataSetService.updatePrincipal(dto);
  }

  @Override
  public Pagination<AtuCaseScriptResultDto> queryScriptByPlan(QueryByPage<AtuCaseScriptQueryDto> dto) {
    if (!StringUtils.isBlank(dto.getQuery().getPlanId())) {
      ResultWrapper<List<String>> resultList = executePlanFeignClient.queryScriptLinkByPlan(dto.getQuery().getPlanId());
      List<String> scriptList = resultList.getData();
      if (scriptList != null && scriptList.size() > 0){
        dto.getQuery().setScriptList(scriptList);
      }else {
        dto.getQuery().setScriptList(null);
      }
    }
    return queryScriptByPath(dto);
  }

  @Override
  public List<AtuPlanScriptReturnDto> feignQueryScriptId(AtuPlanScriptSaveDto dto) {
    Set<AtuCaseDataSet> resultSet = new HashSet<>();
    //全选的节点
    if (dto.getPathList() != null && dto.getPathList().size() > 0) {
      for (String path : dto.getPathList()) {
        List<AtuCaseDataSet> scriptList = this.atuCaseDataSetService.queryPlanScriptByPath(dto.getProId(), path);
        resultSet.addAll(scriptList);
      }
    }
    //勾选的脚本
    if (dto.getSelectList() != null && dto.getSelectList().size()>0) {
      List<AtuCaseDataSet> queryList = this.atuCaseDataSetService.querySetByList(dto.getSelectList());
      resultSet.addAll(queryList);
    }
    //不勾选的脚本
    if (dto.getUnSelectList() != null && dto.getUnSelectList().size() > 0) {
      Iterator<AtuCaseDataSet> iterator = resultSet.iterator();
      if (iterator.hasNext()) {
        for (String scriptId : dto.getUnSelectList()) {
          if (iterator.next().getScriptId().equals(scriptId)) {
            iterator.remove();
          }
        }
      }
    }
    List<AtuPlanScriptReturnDto> resultList = new ArrayList<>();
    for (AtuCaseDataSet dataSet : resultSet) {
      AtuPlanScriptReturnDto returnDto = new AtuPlanScriptReturnDto();
      returnDto.setScriptId(dataSet.getScriptId());
      returnDto.setScriptType(dataSet.getScriptType());
      resultList.add(returnDto);
    }
    return resultList;
  }



  public Set<String> queryPlanScriptIds(String planId){
    Set<String> scriptSet = new HashSet<>();
    //feign调用查询计划关联的用例集
    ResultWrapper<List<String>> resultList = executePlanFeignClient.queryScriptLinkByPlan(planId);
    if (resultList.getData() == null || resultList.getData().size() == 0) {
      return scriptSet;
    }
    //用例集查询
    List<AtuCaseDataSet> atuCaseDataSets = this.atuCaseDataSetService.querySetByList(resultList.getData());
    if (atuCaseDataSets == null || atuCaseDataSets.size() == 0) {
      return scriptSet;
    }

    List<String> sceneList = new ArrayList<>();
    atuCaseDataSets.forEach(one -> {
      if (one.getScriptType().equals(ScriptConstant.SCRIPT_TYPE_SCENE)) {
        //场景脚本
        sceneList.add(one.getScriptId());
      } else if (one.getScriptType().equals(ScriptConstant.SCRIPT_TYPE_ANDROID)
              || one.getScriptType().equals(ScriptConstant.SCRIPT_TYPE_IOS)) {
        //安卓 IOS脚本
        scriptSet.add(one.getScriptId());
      }
    });

    if (sceneList.size() > 0) {
      List<AtuScriptInfo> scriptInfoList = sceneNodeInfoService.queryScriptType(sceneList);
      for (AtuScriptInfo atuScriptInfo : scriptInfoList) {
        scriptSet.add(atuScriptInfo.getId());
      }
    }
    return scriptSet;
  }

  public List<String> queryScriptPlatforms(String planId){
    List<String> platforms = new ArrayList<>();
    Set<String> scriptIdSet = queryPlanScriptIds(planId);
    if (scriptIdSet.size() == 0) {
      //解析出来的脚本为空
      logger.info("缺少安卓、IOS类型的脚本，查询应用结果为空");
      return platforms;
    }
    return atuScriptInfoService.queryScriptPlatforms(scriptIdSet);
  }

    @Override
    public AdvancedQueryOptions advancedQueryOptions(String projectId) {
      AdvancedQueryOptions options = new AdvancedQueryOptions();
      options.setManagerList(new ArrayList<>());
      options.setCreatorList(new ArrayList<>());
      options.setUpdaterList(new ArrayList<>());
      List<String> mangerList = atuCaseDataSetService.selectManagerByProject(projectId);
      Set<Long> userIds = new HashSet<>();
      if (!CollectionUtils.isEmpty(mangerList)) {
        mangerList.forEach(id -> {
          if (id.length() <= 20) {
            userIds.add(Long.valueOf(id));
          }
        });
      }
      List<String> creatorList = atuCaseDataSetService.selectCreatorByProject(projectId);
      if (!CollectionUtils.isEmpty(creatorList)) {
        creatorList.forEach(id -> {
          if (id.length() <= 20) {
            userIds.add(Long.valueOf(id));
          }
        });
      }
      List<String> updaterList = atuCaseDataSetService.selectUpdaterByProject(projectId);
      if (!CollectionUtils.isEmpty(updaterList)) {
        updaterList.forEach(id -> {
          if (id.length() <= 20) {
            userIds.add(Long.valueOf(id));
          }
        });
      }
      if (CollectionUtils.isEmpty(userIds)){
        return options;
      }
      List<UserDTO> userDTOS = monsterCommonFeignClient.getUserByIds(new ArrayList<>(userIds));
      userDTOS.forEach(user -> {
        if (mangerList.contains(user.getId().toString())) {
          options.getManagerList().add(UserOptions.userDTOtoUserOptions(user));
        }
        if (creatorList.contains(user.getId().toString())) {
          options.getCreatorList().add(UserOptions.userDTOtoUserOptions(user));
        }
        if (updaterList.contains(user.getId().toString())) {
          options.getUpdaterList().add(UserOptions.userDTOtoUserOptions(user));
        }
      });
      return options;
    }

    @Override
    public AdvancedQueryOptions picusAdvancedQueryOptions(String projectId) {
      AdvancedQueryOptions options = new AdvancedQueryOptions();
      options.setManagerList(new ArrayList<>());
      List<String> mangerList = atuCaseDataSetService.selectManagerByProject(projectId);
      Set<Long> userIds = new HashSet<>();
      if (!CollectionUtils.isEmpty(mangerList)) {
        mangerList.forEach(id -> {
          if (id.length() <= 20) {
            userIds.add(Long.valueOf(id));
          }
        });
      }
      if (CollectionUtils.isEmpty(userIds)){
        return options;
      }
      List<UserDTO> userDTOS = monsterCommonFeignClient.getUserByIds(new ArrayList<>(userIds));
      userDTOS.forEach(user -> {
        if (mangerList.contains(user.getId().toString())) {
          options.getManagerList().add(UserOptions.userDTOtoUserOptions(user));
        }
      });
      return options;
    }

  private AtuCaseDataSet getCommonNode(){
    AtuCaseDataSet commonNode = (AtuCaseDataSet)redisTemplate.opsForValue().get(commonKey);
    if (ObjectUtils.isEmpty(commonNode)){
      AtuCaseDataSet set = new AtuCaseDataSet();
      set.setSetName(ScriptConstant.COMMON_DATA_SET);
      set.setTenantId(ScriptConstant.SYSTEM_TENANT_ID);
      List<AtuCaseDataSet> query = this.atuCaseDataSetService.query(set);
      commonNode = query.get(0);
      redisTemplate.opsForValue().set(commonKey,query.get(0));
    }
    return commonNode;
  }

  private AtuCaseDataSet getSceneNode(){
    AtuCaseDataSet sceneNode = (AtuCaseDataSet)redisTemplate.opsForValue().get(sceneKey);
    if (ObjectUtils.isEmpty(sceneNode)) {
      AtuCaseDataSet set = new AtuCaseDataSet();
      set.setSetName(ScriptConstant.SCENE_DATA_SET);
      set.setTenantId(ScriptConstant.SYSTEM_TENANT_ID);
      List<AtuCaseDataSet> query = this.atuCaseDataSetService.query(set);
      sceneNode = query.get(0);
      redisTemplate.opsForValue().set(sceneKey,query.get(0));
    }
    return sceneNode;
  }


  private List<AtuCaseDataSetMenuDto> queryTreeByPro(AtuCaseDataSet dto) {
    //查询系统下所有用例集目录
    dto.setLeaf(false);
    dto.setTenantId(NKSecurityContext.getTenantId());
    List<AtuCaseDataSet> querySetByName = atuCaseDataSetService.querySetByName(dto);

    //没数据的情况
    if (StringUtils.isBlank(dto.getSetName())) {
      querySetByName.add(getCommonNode());
      querySetByName.add(getSceneNode());
    }

    //组装树
    return createdTree(querySetByName, dto.getProjectId());

  }


  private List<AtuCaseDataSetMenuDto> queryTreeByProAndName(AtuCaseDataSet dto) {
    //查询用例集目录
    dto.setLeaf(false);
    List<AtuCaseDataSet> list = atuCaseDataSetService.querySetByName(dto);
    Set<String> pathList = new HashSet<>();
    list.forEach(one -> {
      List<String> query = atuCaseDataSetService.queryByPath(one.getId());
      pathList.addAll(query);
    });
    //找出所有节点
    Set<String> nodeSet = new HashSet<>();
    for (String path : pathList) {
      String[] split = path.split("/");
      nodeSet.addAll(Arrays.asList(split));
    }
    //没数据的情况
    if (StringUtils.isBlank(dto.getSetName())) {
      nodeSet.add(getCommonNode().getId());
      nodeSet.add(getSceneNode().getId());
    }
    List<AtuCaseDataSet> setList = new ArrayList<>();
    if (nodeSet.size() > 0) {
      //查询所有节点
      setList = this.atuCaseDataSetService.queryTreeNode(new ArrayList<>(nodeSet));
    }
    //组装树
    return createdTree(setList, dto.getProjectId());
  }

  private List<AtuCaseDataSetMenuDto> createdTree(List<AtuCaseDataSet> setList,String proId){
    //找出首节点
    List<AtuCaseDataSetMenuDto> treeList = new ArrayList<>();
    if (setList.size() == 0){
      return treeList;
    }
    setList.forEach( one -> {
      if (one.getParentId().equals(ScriptConstant.DATA_FIRST_NODE)){
        AtuCaseDataSetMenuDto firstNode = new AtuCaseDataSetMenuDto();
        BeanUtils.copyProperties(one,firstNode);
        firstNode.setProjectId(proId);
        if (firstNode.getSetName().equals(ScriptConstant.SCENE_DATA_SET)){
          firstNode.setLeaf(true);
          treeList.add(0, firstNode);
        } else {
          treeList.add(firstNode);
        }
      }
    });
    if (treeList.size()>0){
      treeList.forEach( one -> {
        List<AtuCaseDataSetMenuDto> childNode = findChildNode(setList, one);
        if (childNode.size()>0){
          one.setChildNode(childNode);
        }else {
          one.setLeaf(true);
        }
      });
    }
    return treeList;
  }

  private List<AtuCaseDataSetMenuDto> findChildNode(List<AtuCaseDataSet> setList,AtuCaseDataSetMenuDto menu){
    List<AtuCaseDataSetMenuDto> childList = new ArrayList<>();
    for (AtuCaseDataSet dataSet : setList) {
      if (dataSet.getParentId().equals(menu.getId())) {
        AtuCaseDataSetMenuDto childNode = new AtuCaseDataSetMenuDto();
        BeanUtils.copyProperties(dataSet,childNode);
        //非叶子节点
        if (!childNode.getLeaf()){
          List<AtuCaseDataSetMenuDto> child = findChildNode(setList, childNode);
          if (child.size() == 0){
            childNode.setLeaf(true);
          }
          childNode.setChildNode(child);
          childList.add(childNode);
        }
      }
    }
    return childList;
  }
}
