package com.friday.tooldriver.service.rpa.supplier.smartrpa;

import com.friday.base.common.response.DubboResult;
import com.friday.operation.api.keepalive.dto.taieoc.MachineInfoDto;
import com.friday.operation.api.tooldriver.dto.common.DriverBase;
import com.friday.operation.api.tooldriver.dto.rpa.CodePackageDto;
import com.friday.operation.api.tooldriver.dto.rpa.CodePackageFilter;
import com.friday.operation.api.tooldriver.dto.rpa.ReleaseDto;
import com.friday.operation.api.tooldriver.dto.rpa.ReleaseFilter;
import com.friday.operation.api.tooldriver.service.ICapabilityDriver;
import com.friday.operation.api.tooldriver.service.IProcess;
import com.friday.operation.api.keepalive.constant.taieoc.TaieOcConstants;
import com.friday.tooldriver.constants.DriverSystemCode;
import com.friday.tooldriver.constants.TaieOcManageCode;
import com.friday.tooldriver.dto.smartrpa.SmartRobotDto;
import com.friday.tooldriver.mapper.taieoc.OcGroupMapper;
import com.friday.tooldriver.po.taieoc.OcGroupPo;
import com.friday.tooldriver.po.taieoc.OcProcessCommitPo;
import com.friday.tooldriver.service.rpa.smartRPA.ProcessReleaseManage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;

@Service
@Slf4j
public class ProcessManager implements IProcess {
    @Autowired
    private ICapabilityDriver capabilityDriver;

    @Autowired
    private RobotManager robotManager;

    @Autowired
    private OcGroupMapper ocGroupMapper;

    @Autowired
    private ProcessReleaseManage processReleaseManage;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public DubboResult<CodePackageDto> uploadPackage(MachineInfoDto infoDto, CodePackageDto pkg) {
        try{
            if(!verifyInputParam(infoDto))
            {
                return DubboResult.newFailure(TaieOcManageCode.PARAM_VERIFY_ERROR.getCode(),TaieOcManageCode.PARAM_VERIFY_ERROR.getMessage());
            }
            // 查询中控信息
            DubboResult<SmartRobotDto> smartRobotDtoDubboResult = robotManager.queryRobotByKey(infoDto.getMachineCode() + infoDto.getMachineUser());
            if(!smartRobotDtoDubboResult.success()){
                return DubboResult.newFailure(TaieOcManageCode.ROBOT_NOT_EXIST.getCode(), TaieOcManageCode.ROBOT_NOT_EXIST.getMessage());
            }
            SmartRobotDto smartRobotDto = smartRobotDtoDubboResult.getObject();
            return capabilityDriver.uploadPackage(DriverBase.builder()
                            .tenantKey(String.valueOf(smartRobotDto.getOcTenantId()))
                    .build(), pkg);
        }catch(Exception e){
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(),e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), DriverSystemCode.FAIL.getMessage());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public DubboResult deletePackageByKey(MachineInfoDto infoDto, String key) {
        try {
            if(!verifyInputParam(infoDto))
            {
                return DubboResult.newFailure(TaieOcManageCode.PARAM_VERIFY_ERROR.getCode(),TaieOcManageCode.PARAM_VERIFY_ERROR.getMessage());
            }

            return capabilityDriver.deletePackageByKey(DriverBase.builder().tenantKey(String.valueOf(getOcTenantId(infoDto))).build(),key);

        } catch (Exception e) {
            log.error(TaieOcManageCode.FAIL.toString(), e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return DubboResult.newFailure(TaieOcManageCode.FAIL.getCode(), TaieOcManageCode.FAIL.getMessage());
        }
    }


    @Override
    public DubboResult<ArrayList<CodePackageDto>> queryPackages(MachineInfoDto infoDto, CodePackageFilter filter) {
        try{
            if(!verifyInputParam(infoDto))
            {
                return DubboResult.newFailure(TaieOcManageCode.PARAM_VERIFY_ERROR.getCode(),TaieOcManageCode.PARAM_VERIFY_ERROR.getMessage());
            }
            Long ocTenantId = getOcTenantId(infoDto);
            if(ocTenantId == null){
                return DubboResult.newFailure(TaieOcManageCode.ROBOT_NOT_EXIST.getCode(), TaieOcManageCode.ROBOT_NOT_EXIST.getMessage());
            }
            return capabilityDriver.queryPackages(DriverBase.builder().tenantKey(String.valueOf(ocTenantId)).build(),filter);
        }catch (Exception e){
            log.error(TaieOcManageCode.FAIL.toString(),e);
            return DubboResult.newFailure(TaieOcManageCode.FAIL.getCode(),e.getMessage());
        }

    }

    private Boolean verifyInputParam(MachineInfoDto infoDto){
        if((infoDto.getMachineCode() != null && infoDto.getMachineUser() != null) || infoDto.getOcTenantKey() != null){
            return true;
        }
        return false;
    }

    private Long getOcTenantId(MachineInfoDto infoDto) throws Exception {
        if(infoDto.getOcTenantKey() !=null){
            return Long.parseLong(infoDto.getOcTenantKey());
        }
        DubboResult<SmartRobotDto> smartRobotDtoDubboResult = robotManager.queryRobotByKey(infoDto.getMachineCode() + infoDto.getMachineUser());
        if(!smartRobotDtoDubboResult.success()){
            throw new Exception(smartRobotDtoDubboResult.getMessage());
        }
        return smartRobotDtoDubboResult.getObject().getOcTenantId();
    }




    @Override
    @Transactional(rollbackFor = Exception.class)
    public DubboResult<ReleaseDto> releaseProcess(MachineInfoDto infoDto, ReleaseDto release) {
        if(!verifyInputParam(infoDto))
        {
            return DubboResult.newFailure(TaieOcManageCode.PARAM_VERIFY_ERROR.getCode(),TaieOcManageCode.PARAM_VERIFY_ERROR.getMessage());
        }
        try{
            // 判断代码包版本是否存在
            Long ocTenantId = getOcTenantId(infoDto);
            if(ocTenantId == null){
                return DubboResult.newFailure(TaieOcManageCode.ROBOT_NOT_EXIST.getCode(), TaieOcManageCode.ROBOT_NOT_EXIST.getMessage());
            }
            // 获取组信息
            OcGroupPo ocGroupPo = ocGroupMapper.selectProcessGroup(release.getName(), ocTenantId);
            if(ObjectUtils.isEmpty(ocGroupPo)){
                return DubboResult.newFailure(TaieOcManageCode.GROUP_NOT_EXIST.getCode(), TaieOcManageCode.GROUP_NOT_EXIST.getMessage());
            }
            return capabilityDriver.releaseProcess(DriverBase.builder().tenantKey(String.valueOf(ocTenantId)).groupKey(String.valueOf(ocGroupPo.getId())).build(), release);

        }catch (Exception e){
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(),e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }


    @Override
    public DubboResult<ArrayList<ReleaseDto>> queryProcessReleases(MachineInfoDto infoDto, ReleaseFilter filter) {
        if(!verifyInputParam(infoDto))
        {
            return DubboResult.newFailure(TaieOcManageCode.PARAM_VERIFY_ERROR.getCode(),TaieOcManageCode.PARAM_VERIFY_ERROR.getMessage());
        }
        try{
            Long ocTenantId = getOcTenantId(infoDto);
            if(ocTenantId == null){
                return DubboResult.newFailure(TaieOcManageCode.ROBOT_NOT_EXIST.getCode(), TaieOcManageCode.ROBOT_NOT_EXIST.getMessage());
            }

            return capabilityDriver.queryProcessReleases(DriverBase.builder().tenantKey(String.valueOf(ocTenantId)).build(), filter);
        }catch(Exception e){
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(),e);
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }

    @Override
    public DubboResult<String> obtainProcessMaxVersionFileKey(MachineInfoDto infoDto, CodePackageFilter filter) {
        try{
            Long ocTenantId = getOcTenantId(infoDto);
            if(ocTenantId == null){
                return DubboResult.newFailure(TaieOcManageCode.ROBOT_NOT_EXIST.getCode(), TaieOcManageCode.ROBOT_NOT_EXIST.getMessage());
            }
            OcProcessCommitPo ocProcessCommitPo = processReleaseManage.obtainMaxVersion(String.valueOf(ocTenantId), filter.getName(), filter.getFileType());
            if(ObjectUtils.isEmpty(ocProcessCommitPo)){
                return DubboResult.newSuccess(TaieOcConstants.EMPTY_STRING);
            }
            return DubboResult.newSuccess(ocProcessCommitPo.getFileKey());
        }catch (Exception e){
            log.error(TaieOcManageCode.INTERNAL_ERROR.toString(), e);
            return DubboResult.newFailure(TaieOcManageCode.INTERNAL_ERROR.getCode(), TaieOcManageCode.INTERNAL_ERROR.getMessage());
        }
    }

}


