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

import com.alibaba.fastjson.JSONObject;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.constants.BaseDefineDependencyConstants;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.dto.PageQueryDTO;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.entity.Environment;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.exception.InvalidException;
import com.hzbank.testteam.autotest.dependencies.baseDefineDependency.vo.ResponseVO;
import com.hzbank.testteam.autotest.dependencies.monsterDependency.dto.SystemDTO;
import net.northking.cctp.common.cache.EntityNameCache;
import net.northking.cctp.common.cache.EntityNameCatalog;
import net.northking.cctp.common.db.annotation.DatabaseReadOnly;
import net.northking.cctp.common.exception.PlatformRuntimeException;
import net.northking.cctp.common.feign.ApiAtsEnviromentFeign;
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.project.bus.feign.HzBankFeign;
import net.northking.cctp.project.bus.feign.PlatformFeign;
import net.northking.cctp.project.bus.feign.TestBugFeign;
import net.northking.cctp.project.config.TaskSyncConfig;
import net.northking.cctp.project.constants.ProjectAppError;
import net.northking.cctp.project.constants.ProjectConstants;
import net.northking.cctp.project.db.entity.CpProject;
import net.northking.cctp.project.db.entity.CpProjectSoftware;
import net.northking.cctp.project.db.service.CpProjectService;
import net.northking.cctp.project.db.service.CpProjectSoftwareService;
import net.northking.cctp.project.dto.project.CpProjectDetailDto;
import net.northking.cctp.project.dto.project.CpProjectEnvOptionDto;
import net.northking.cctp.project.dto.project.CpProjectEnvQueryDto;
import net.northking.cctp.project.dto.project.ProjectSimpleInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 系统基本信息表服务实现类openLeafProject
 *
 * @author maven-cctp-plugin
 * @since 1.0
 */

@Service
@ConditionalOnMissingBean(name = "CpProjectApiServiceImpl")
public class CpProjectApiServiceImpl  implements CpProjectApiService {
    /**
     * 日志
     */
    private final static Logger logger = LoggerFactory.getLogger(CpProjectApiServiceImpl.class);

    @Autowired
    private CpProjectService cpProjectService;

    @Autowired
    private EntityNameCache entityNameCache;


    @Autowired
    private CpProjectSoftwareService cpProjectSoftwareService;

    @Autowired
    private TestBugFeign testBugFeign;

    @Autowired
    private PlatformFeign platformFeign;


    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Autowired
    private CpProjectApiService cpProjectApiService;

    @Autowired
    private ApiAtsEnviromentFeign apiAtsEnviromentFeign;
    @Autowired
    private HzBankFeign hzBankFeign;
    @Autowired
    private TaskSyncConfig taskSyncConfig;



    @Override
    public List<ProjectSimpleInfo> queryAllProjectByTenant() throws ParseException {
        return this.cpProjectService.queryAllProjectByTenant();
    }

    @Override
    @DatabaseReadOnly
    public CpProjectDetailDto findByPK(String uuid) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("id",Long.parseLong(uuid));
        SystemDTO systemDTO = hzBankFeign.selectOneByMap(jsonObject);
        if (Objects.isNull(systemDTO)) {
            return null;
        }
        CpProjectDetailDto dto = new CpProjectDetailDto();
        dto.setId(uuid);
        dto.setTenantId(taskSyncConfig.getTenantId());
        dto.setLeaf(true);
        dto.setName(systemDTO.getName());
        dto.setRootId(String.valueOf(systemDTO.getId()));
        dto.setParentId("TOP");
        dto.setIdPath(uuid);
        if (!Objects.isNull(systemDTO.getSystemManager())) {
            List<String> list = new ArrayList<>();
            list.add(String.valueOf(systemDTO.getSystemManager()));
            dto.setUserId(list);
            dto.setUsername(entityNameCache.translateById(EntityNameCatalog.MONSTER_USER.name(), String.valueOf(systemDTO.getSystemManager())));
        }

        //系统软件获取
        CpProjectSoftware cpProjectSoftware = new CpProjectSoftware();
        cpProjectSoftware.setProjectId(uuid);
        List<CpProjectSoftware> projectSoftwares = this.cpProjectSoftwareService.query(cpProjectSoftware);
        if (projectSoftwares != null && projectSoftwares.size() > 0) {
            List<String> list = new ArrayList<>();
            projectSoftwares.forEach(software -> {
                list.add(software.getSoftwareId());
            });
            dto.setSoftwareId(list);
        }

        //判断系统是否产生产物
        try {
            // 根据key获取缓存 如果是true那就直接设置caseDefeact为false，如果是false，那么请求feign，
            Object testBug = redisTemplate.opsForValue().get(ProjectConstants.PRO_QUERY_DATA + uuid);
            boolean testBugFlag = false;
            if (testBug  != null) {
                testBugFlag = (boolean) testBug;
            }
            if (testBugFlag) {
                dto.setCaseDefectTag(false);
            } else {
                //缺陷（不可删除）
                ResultWrapper<Boolean> tb = testBugFeign.queryUserIsCreatedBugByProId(dto.getId(), null);
                if (tb.getData()) {//如果有不能修改用例缺陷属性模板
                    dto.setCaseDefectTag(false);
                    redisTemplate.opsForValue().set(ProjectConstants.PRO_QUERY_DATA + uuid, tb.getData());
                }
            }
        } catch (Exception e) {
            logger.error("feign调用失败 ",e);
        }
        List<Environment> environments = this.selectProjectEnvs(uuid);
        List<String> envNames = new ArrayList<>();
        List<String> envIds = new ArrayList<>();
        for (int i = 0; i < environments.size(); i++) {
            envNames.add(environments.get(i).getName());
            envIds.add(environments.get(i).getId().toString());
        }
        dto.setEnvIds(envIds);
        dto.setEnvNames(envNames);
        return dto;
    }


    @Override
    public List<ProjectSimpleInfo> queryProByDevice() throws ParseException {
        List<ProjectSimpleInfo> result = this.cpProjectService.queryProByDevice(NKSecurityContext.getTenantId());
        return result;
    }

    @Override
    public ProjectSimpleInfo getProjectInfo(CpProject project) {
        if (project == null || StringUtils.isBlank(project.getId())) {
            throw new PlatformRuntimeException(ProjectAppError.PROJECT_ID_IS_EMPTY);
        }
        ProjectSimpleInfo info = this.cpProjectService.getProjectInfo(project);
        return info;
    }

    @Override
    public List<String> selectEnvIds(String proId) {
        Long projectId = null;
        try {
            projectId = Long.valueOf(proId);
        } catch (NumberFormatException e) {
            logger.error("系统Id类型转化异常");
            throw new InvalidException("系统Id类型转化异常");
        }
        ResponseVO<List<Environment>> responseVo = apiAtsEnviromentFeign.listByProject(projectId);
        if (responseVo == null || !responseVo.getCode().equals(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_SUCCESS)) {
            throw new InvalidException("服务间调用获取系统环境失败");
        }
        return responseVo.getData().stream().map(e -> e.getId().toString()).collect(Collectors.toList());
    }

    @Override
    public List<String> queryEnvListSeq(String proId) {
        return selectEnvIds(proId);
    }

    @Override
    public List<Environment> selectProjectEnvs(String proId) {
        Long projectId = null;
        try {
            projectId = Long.valueOf(proId);
        } catch (NumberFormatException e) {
            logger.error("系统Id类型转化异常");
            throw new InvalidException("系统Id类型转化异常");
        }
        ResponseVO<List<Environment>> responseVo = apiAtsEnviromentFeign.listByProject(projectId);
        if (responseVo == null || !responseVo.getCode().equals(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_SUCCESS)) {
            throw new InvalidException("服务间调用获取系统环境失败");
        }
        return responseVo.getData();
    }
	
    @Override
    public Map<String, String> feignQueryProData(String proId) {
        Map<String,String> result = new HashMap<>();
        String proCode = cpProjectService.queryProCode(proId);
        result.put(ProjectConstants.PRO_CODE,proCode);
        return result;
    }

    @Override
    public List<CpProjectEnvOptionDto> selectEnvOptions(String projectId) {
        ResponseVO<List<Environment>> responseVo = apiAtsEnviromentFeign.listByProject(Long.valueOf(projectId));
        if (responseVo == null || !responseVo.getCode().equals(BaseDefineDependencyConstants.SYSTEM_RESPONSE_CODE_SUCCESS)) {
            throw new InvalidException("服务间调用获取系统环境失败");
        }
        List<CpProjectEnvOptionDto> envOptionList = new ArrayList<>();
        List<Environment> data = responseVo.getData();
        if (CollectionUtils.isEmpty(data)) {
            return new ArrayList<>();
        }
        for (Environment projectEnv : responseVo.getData()) {
            CpProjectEnvOptionDto optionDto = new CpProjectEnvOptionDto();
            optionDto.setLabel(projectEnv.getName());
            optionDto.setValue(projectEnv.getId().toString());
            envOptionList.add(optionDto);
        }
        return envOptionList;
    }

    @Override
    public ResponseVO<Object> getATSProjectEnvVo(QueryByPage<CpProjectEnvQueryDto> cpProjectEnvQueryDto) {
        PageQueryDTO pageQueryDTO = new PageQueryDTO();
        pageQueryDTO.setCurrent(cpProjectEnvQueryDto.getPageNo());
        pageQueryDTO.setSize(cpProjectEnvQueryDto.getPageSize());
        CpProjectEnvQueryDto query = cpProjectEnvQueryDto.getQuery();
        Map<String, Object> params = new HashMap<>();
        params.put("keyword", query.getEnvName());
        params.put("projectId", query.getProIds().get(0));
        pageQueryDTO.setParams(params);
        return apiAtsEnviromentFeign.getATSEnvData(pageQueryDTO);
    }
}
