package cd.casic.ci.process.process.service.aflManager.impl;

import cd.casic.ci.process.dto.req.aflManager.AflManagerReq;
import cd.casic.ci.process.dto.resp.aflManager.AflPlotInfoResp;
import cd.casic.ci.process.dto.resp.resource.ResourceDetailResp;
import cd.casic.ci.process.engine.constant.PipelineVariableConstant;
import cd.casic.ci.process.engine.manager.RunContextManager;
import cd.casic.ci.process.engine.runContext.BaseRunContext;
import cd.casic.ci.process.process.converter.AflManagerConverter;
import cd.casic.ci.process.process.dao.aflManager.AflPlotInfoDao;
import cd.casic.ci.process.process.dataObject.aflManager.AflPlotInfo;
import cd.casic.ci.process.process.service.aflManager.AflPlotInfoService;
import cd.casic.ci.process.process.service.resource.ResourceManagerService;
import cd.casic.ci.process.util.SftpUploadUtil;
import cd.casic.framework.commons.exception.ServiceException;
import cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants;
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
import cd.casic.module.machine.utils.CryptogramUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import de.danielbechler.util.Collections;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author HopeLi
 * @version v1.0
 * @ClassName TargetVersionServiceImpl
 * @Date: 2025/5/17 15:20
 * @Description:
 */
@Service
@Slf4j
public class AflPlotInfoServiceImpl extends ServiceImpl<AflPlotInfoDao, AflPlotInfo> implements AflPlotInfoService {
    private static final String remoteFilePath = "/home/casic/706/yunqi/";

    @Resource
    private RunContextManager runContextManager;

    @Resource
    private ResourceManagerService resourceManagerService;


    @Override
    public String saveAflPlotInfo(AflManagerReq req) throws SftpUploadUtil.SftpUploadException {
        if (StringUtils.isEmpty(req.getPipelineId()) || StringUtils.isEmpty(req.getTaskId())){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"pipelineId或者taskId不能为空");
        }

        BaseRunContext runContext = runContextManager.getContext(req.getPipelineId());
        if (ObjectUtils.isEmpty(runContext)){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"未找到运行上下文");
        }
        String resourceId = runContext.getGlobalVariables().get(PipelineVariableConstant.AFL_RESOURCE_MANAGER_ID_KEY) instanceof String ? ((String) runContext.getGlobalVariables().get(PipelineVariableConstant.AFL_RESOURCE_MANAGER_ID_KEY)) : null;
//        String resourceId = "2";
        if (StringUtils.isEmpty(resourceId)){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"未找到资源");
        }

        ResourceDetailResp resourceById = resourceManagerService.findResourceDetailById(resourceId);
        if (resourceById == null || resourceById.getMachineInfo() == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"资源信息错误");
        }

        MachineInfoDO resourceMachine = resourceById.getMachineInfo();
        resourceMachine.setPassword(CryptogramUtil.doDecrypt(resourceMachine.getPassword()));
        AflPlotInfo aflPlotInfo = SftpUploadUtil.downloadFileSftpForLastLineAndSetAflPlotInfo(resourceMachine.getHostIp(), resourceMachine.getSshPort(), resourceMachine.getUsername(), resourceMachine.getPassword(),null, remoteFilePath + "PIP_" + req.getPipelineId() + "/ai_afl/default/plot_data");

        //获取远程文件流，并保存到数据库
        List<String> sourceFilePaths = new ArrayList<>();
        sourceFilePaths.add(remoteFilePath + "PIP_" + req.getPipelineId() + "/ai_afl/default/plot_data");
        Map<String, byte[]> stringMap = SftpUploadUtil.copyRemoteFilesToByteArray(resourceMachine.getHostIp(), resourceMachine.getSshPort(), resourceMachine.getUsername(), resourceMachine.getPassword(), null, sourceFilePaths);

        aflPlotInfo.setFileContent(stringMap.get(sourceFilePaths.get(0)));
        aflPlotInfo.setPipelineId(req.getPipelineId());
        if (!StringUtils.isEmpty(req.getTaskId())){
            aflPlotInfo.setTaskId(req.getTaskId());
        }
        if (!StringUtils.isEmpty(req.getPipelineHistoryId())){
            aflPlotInfo.setPipelineHistoryId(req.getPipelineHistoryId());
        }
        aflPlotInfo.setGroupIdentifier(req.getGroupIdentifier());
        baseMapper.insert(aflPlotInfo);

        return aflPlotInfo.getGroupIdentifier();
    }

    @Override
    public void updateHistoryPipelineIdByAflPlotInfo(AflManagerReq req) {
        if (!StringUtils.isEmpty(req.getGroupIdentifier())){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"groupIdentifier不能为空");
        }
        QueryWrapper<AflPlotInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("group_identifier", req.getGroupIdentifier());
        List<AflPlotInfo> aflPlotInfos = baseMapper.selectList(wrapper);
        if (!Collections.isEmpty(aflPlotInfos)){
            aflPlotInfos.forEach(o->{
                o.setPipelineHistoryId(req.getPipelineHistoryId());
            });
        }
        baseMapper.updateBatch(aflPlotInfos);
    }

    @Override
    public AflPlotInfoResp findAflPlotInfoNow(AflManagerReq req) throws SftpUploadUtil.SftpUploadException {
        if (StringUtils.isEmpty(req.getPipelineId()) || StringUtils.isEmpty(req.getTaskId())){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"pipelineId或者taskId不能为空");
        }

        BaseRunContext runContext = runContextManager.getContext(req.getPipelineId());
        if (ObjectUtils.isEmpty(runContext)){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"未找到运行上下文");
        }
        String resourceId = runContext.getGlobalVariables().get(PipelineVariableConstant.AFL_RESOURCE_MANAGER_ID_KEY) instanceof String ? ((String) runContext.getGlobalVariables().get(PipelineVariableConstant.AFL_RESOURCE_MANAGER_ID_KEY)) : null;
//        String resourceId = "2";
        if (StringUtils.isEmpty(resourceId)){
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"未找到资源");
        }

        ResourceDetailResp resourceById = resourceManagerService.findResourceDetailById(resourceId);
        if (resourceById == null || resourceById.getMachineInfo() == null) {
            throw new ServiceException(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR.getCode(),"资源信息错误");
        }

        MachineInfoDO resourceMachine = resourceById.getMachineInfo();
        AflPlotInfo aflPlotInfo = SftpUploadUtil.downloadFileSftpForLastLineAndSetAflPlotInfo(resourceMachine.getHostIp(), resourceMachine.getSshPort(), resourceMachine.getUsername(), CryptogramUtil.doDecrypt(resourceMachine.getPassword()),null, remoteFilePath + "PIP_" + req.getPipelineId() + "/ai_afl/default/plot_data");

        return AflManagerConverter.INSTANCE.toAflPlotInfoResp(aflPlotInfo);
    }

    @Override
    public List<AflPlotInfoResp> findAflPlotInfoListByHistory(AflManagerReq req) {
        QueryWrapper<AflPlotInfo> wrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(req.getId())){
            wrapper.eq("id",req.getId());
        }
        if (!ObjectUtils.isEmpty(req.getPipelineId())){
            wrapper.eq("pipeline_id",req.getPipelineId());
        }
        if (!ObjectUtils.isEmpty(req.getPipelineHistoryId())){
            wrapper.eq("pipeline_history_id",req.getPipelineHistoryId());
        }
        if (!ObjectUtils.isEmpty(req.getTaskId())){
            wrapper.eq("task_id",req.getTaskId());
        }
        if (!ObjectUtils.isEmpty(req.getGroupIdentifier())){
            wrapper.eq("group_identifier",req.getGroupIdentifier());
        }

        List<AflPlotInfo> aflPlotInfos = baseMapper.selectList(wrapper);
        if (ObjectUtils.isEmpty(aflPlotInfos)){
            return new ArrayList<>(0);
        }

        return AflManagerConverter.INSTANCE.toAflPlotInfoRespList(aflPlotInfos);
    }
}
