package com.friday.tooldriver.service.rpa.driverimpl;

import com.alibaba.fastjson.JSONObject;
import com.friday.tooldriver.constants.uipath.*;
import com.friday.tooldriver.dto.uipath.request.*;
import com.friday.tooldriver.dto.uipath.response.*;
import com.friday.tooldriver.service.rpa.supplier.UIPATHService;
import com.google.common.collect.Lists;
import com.friday.base.common.annotation.MethodLog;
import com.friday.base.common.response.DubboResult;
import com.friday.operation.api.distributor.constant.TaieJobState;
import com.friday.operation.api.keepalive.dto.taieoc.OcTenantDetailDto;
import com.friday.operation.api.tooldriver.dto.common.DriverBase;
import com.friday.operation.api.tooldriver.dto.rpa.RobotDto;
import com.friday.operation.api.tooldriver.dto.rpa.*;
import com.friday.tooldriver.constants.DriverSystemCode;
import com.friday.tooldriver.constants.uipath.*;
import com.friday.tooldriver.dto.uipath.request.*;
import com.friday.tooldriver.dto.uipath.response.*;
import com.friday.tooldriver.exception.DriverBusinessException;
import com.friday.tooldriver.service.strategy.ICapabilityDriverService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.friday.operation.api.tooldriver.constant.DriverConstant.*;
import static com.friday.operation.api.tooldriver.constant.LicenseTypeEnum.*;

/**
 * @Author YaoYao
 * @Date Created In 18:52 2022/12/1
 * @Description UIPATH驱动能力实现服务类
 * @Modified By
 */
@Service("UIPATHDriver")
@Slf4j
public class UIPATHDriverServiceImpl implements ICapabilityDriverService {

    @Autowired
    private UIPATHService UiPathService;

    @Override
    public DubboResult<TenantDto> createTenant(DriverBase driverBase, TenantDto tenant) {
        return DubboResult.newSuccess(new TenantDto());
    }

    @Override
    public DubboResult<ArrayList<TenantDto>> queryTenants(DriverBase driverBase, TenantSelectFilter filter) {
        return null;
    }

    @Override
    public DubboResult<TenantDto> queryTenantByKey(DriverBase driverBase, String key) {
        return null;
    }

    @Override
    public DubboResult deleteTenantByKey(DriverBase driverBase, String key) {
        return null;
    }

    @Override
    public DubboResult updateTenantByKey(DriverBase driverBase, String key) {
        return null;
    }

    @Override
    public DubboResult activateTenantByKey(DriverBase driverBase, String key) {
        return null;
    }

    @Override
    public DubboResult<GroupDto> createGroup(DriverBase driverBase, GroupDto group){
        FolderDto folder = FolderDto.builder()
                .displayName(group.getName())
                .description(group.getDescription())
                .feedType(FolderFeedType.Processes.name())
                .permissionModel(FolderPermissionModel.FineGrained.name())
                .build();
        if(StringUtils.isEmpty(group.getParentKey())){
            folder.setProvisionType(FolderProvisionType.Automatic.name());
        } else {
            folder.setParentId(Integer.parseInt(group.getParentKey()));
        }
        DubboResult<FolderDto> result = UiPathService.createFolder(driverBase, folder);
        if(!result.success()){
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
        OcTenantDetailDto ocTenantInfo;
        Integer unattendedMachineId;
        try {
            ocTenantInfo = UiPathService.getOcTenantInfo(driverBase);
            unattendedMachineId = ocTenantInfo.getExtInfo().getInteger("unattendedMachineId");
        } catch (DriverBusinessException e) {
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, e.getMessage());
        }
        //为新建文件夹添加后台运行机器模板
        FolderDto newFolder = result.getObject();
        MachinesFolderAssociationsDto associations = MachinesFolderAssociationsDto.builder()
                .folderId(newFolder.getId())
                .addedMachineIds(Lists.newArrayList(unattendedMachineId))
                .removedMachineIds(Lists.newArrayList())
                .build();
        DubboResult assignTemplateResult = UiPathService.assignTemplateToFolder(driverBase, FoldersUpdateMachinesToFolderAssociationsParametersDto.builder().associations(associations).build());
        if(!assignTemplateResult.success()){
            return DubboResult.newFailure(assignTemplateResult.getCode(), assignTemplateResult.getMessage());
        }
        group.setKey(String.valueOf(result.getObject().getId()));
        return DubboResult.newSuccess(group);
    }

    @Override
    public DubboResult<ArrayList<GroupDto>> queryGroups(DriverBase driverBase, GroupFilter filter) {
        DubboResult<ArrayList<FolderDto>> result = UiPathService.queryFolders(driverBase, new FolderDto());
        if(result.success()){
            List<GroupDto> groups = result.getObject().stream().map(FolderDto::transferToGroupDto).collect(Collectors.toList());
            return DubboResult.newSuccess((ArrayList<GroupDto>) groups);
        } else {
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
    }

    @Override
    public DubboResult<GroupDto> queryGroupByKey(DriverBase driverBase, String key) {
        DubboResult<FolderDto> result = UiPathService.queryFolderById(driverBase, key);
        if(result.success()){
            GroupDto group = result.getObject().transferToGroupDto();
            return DubboResult.newSuccess(group);
        } else {
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
    }

    @Override
    public DubboResult deleteGroupByKey(DriverBase driverBase, String key) {
        return UiPathService.deleteFolderById(driverBase, key);
    }

    @Override
    @MethodLog(desc = "uipath上传代码包")
    public DubboResult<CodePackageDto> uploadPackage(DriverBase driverBase, CodePackageDto pkg) {
        DubboResult<String> result = UiPathService.uploadPackage(driverBase, new File(pkg.getFilePath()));
        if(result.success()){
            pkg.setKey(result.getObject());
            return DubboResult.newSuccess(pkg);
        } else {
            log.error("uipath上传代码包失败", result);
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
    }

    @Override
    public DubboResult deletePackageByKey(DriverBase driverBase, String key) {
        return UiPathService.deletePackageByKey(driverBase, key);
    }

    @Override
    public DubboResult<ArrayList<CodePackageDto>> queryPackages(DriverBase driverBase, CodePackageFilter filter) {
        //根据name查版本
        if(StringUtils.isNotEmpty(filter.getName())){
            DubboResult<ArrayList<ProcessResponseDto>> processResult = UiPathService.getProcessVersionsByName(driverBase, filter.getName());
            if(!processResult.success()){
                return DubboResult.newFailure(processResult.getCode(), processResult.getMessage());
            }
            List<CodePackageDto> codePackages = processResult.getObject().stream().map(ProcessResponseDto::transToCodePackage).collect(Collectors.toList());
            return DubboResult.newSuccess((ArrayList<CodePackageDto>) codePackages);
        }
        return DubboResult.newSuccess(Lists.newArrayList());
    }

    @Override
    public DubboResult<CodePackageDto> queryPackageByKey(DriverBase driverBase, String key) {
        //暂无场景
        return DubboResult.newSuccess(new CodePackageDto());
    }

    @Override
    public DubboResult downloadPackageByKey(DriverBase driverBase, String key, String fileName) {
        String desFileName;
        if(StringUtils.isNotEmpty(fileName)){
            desFileName = fileName + UIPATH_PKG_SUFFIX;
        } else {
            desFileName = key.replace(":", ".") + UIPATH_PKG_SUFFIX;
        }
        return UiPathService.downloadPackageByKey(driverBase, key, desFileName);
    }

    @Override
    public DubboResult<ReleaseDto> releaseProcess(DriverBase driverBase, ReleaseDto release) {
        ProcessReleaseDto processRelease = ProcessReleaseDto.builder()
                .name(release.getName())
                .description(release.getDescription())
                .processKey(release.getCodePackageName())
                .processVersion(release.getProcessVersion())
                .jobPriority(JobPriority.Normal.name())
                .build();
        if(StringUtils.isEmpty(release.getKey())){
            //首次发布
            DubboResult<ProcessReleaseDto> result = UiPathService.releaseProcess(driverBase, processRelease);
            if(result.success()){
                ReleaseDto resultRelease = result.getObject().transferToReleaseDto();
                return DubboResult.newSuccess(resultRelease);
            } else {
                return DubboResult.newFailure(result.getCode(), result.getMessage());
            }
        }
        //再发布
        processRelease.setId(Integer.parseInt(release.getKey()));
        DubboResult result = UiPathService.releaseProcessToSpecificVersion(driverBase, processRelease);
        if(result.success()){
            return DubboResult.newSuccess(release);
        } else {
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
    }

    @Override
    public DubboResult deleteProcessReleaseByKey(DriverBase driverBase, String key) {
        return UiPathService.deleteReleaseByKey(driverBase, key);
    }

    @Override
    public DubboResult<ArrayList<ReleaseDto>> queryProcessReleases(DriverBase driverBase, ReleaseFilter filter) {
        //暂无场景
        return DubboResult.newSuccess(Lists.newArrayList());
    }

    @Override
    public DubboResult<ReleaseDto> queryProcessReleaseByKey(DriverBase driverBase, String key) {
        DubboResult<ProcessReleaseDto> result = UiPathService.queryReleaseByKey(driverBase, key);
        if(result.success()){
            ReleaseDto release = result.getObject().transferToReleaseDto();
            return DubboResult.newSuccess(release);
        } else {
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
    }

    @Override
    public DubboResult<RobotDto> createRobot(DriverBase driverBase, RobotDto robot) {
        UserRequestDto user = UserRequestDto.builder()
                .userName(robot.getName())
                .name(robot.getName())
                .mayHaveUserSession(true)
                .type(UserType.User.name())
                .rolesList(Lists.newArrayList(RoleName.Robot.name()))
                .build();
        if(RobotType.Unattended.name().equals(robot.getType())){
            user.setMayHaveUnattendedSession(true);
            UnattendedRobotDto unattendedRobot = UnattendedRobotDto.builder()
                    .userName(robot.getWhoAmI())
                    .password(robot.getPassword())
                    .build();
            user.setUnattendedRobotDto(unattendedRobot);
        }
        DubboResult<UserResponseDto> addUserResult = UiPathService.addUser(driverBase, user);
        if(!addUserResult.success()){
            return DubboResult.newFailure(addUserResult.getCode(), addUserResult.getMessage());
        }
        robot.setKey(String.valueOf(addUserResult.getObject().getId()));
        return DubboResult.newSuccess(robot);
    }



    @Override
    public DubboResult deleteRobotByKey(DriverBase driverBase, String key) {
        return UiPathService.deleteUserByKey(driverBase, key);
    }

    @Override
    public DubboResult<ArrayList<RobotDto>> queryRobots(DriverBase driverBase, RobotFilter filter) {
        //暂无场景
        return DubboResult.newSuccess(Lists.newArrayList());
    }

    @Override
    @MethodLog(desc = "查询机器状态和许可信息")
    public DubboResult<RobotDto> queryRobotByKey(DriverBase driverBase, String key) {
        DubboResult<RobotExtInfoDto> result = this.queryRobotExtInfoByKey(driverBase, key);
        if(!result.success()){
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
        RobotExtInfoDto robotExt = result.getObject();
        RobotDto robot = RobotDto.builder()
                .ocTenantId(robotExt.getOcTenantId())
                .state(robotExt.getState())
                .name(robotExt.getName())
                .key(robotExt.getKey())
                .password(robotExt.getPassword())
                .whoAmI(robotExt.getWhoAmI())
                .type(robotExt.getType())
                .userName(robotExt.getUserName())
                .authState(robotExt.getAuthState())
                .licensed(robotExt.getLicensed())
                .licenseType(robotExt.getLicenseType())
                .machineCode(robotExt.getMachineCode())
                .build();
        return DubboResult.newSuccess(robot);
    }

    private DubboResult<RobotExtInfoDto> queryRobotExtInfoByKey(DriverBase driverBase, String key){
        DubboResult<UserResponseDto> userResult = UiPathService.queryUserByKey(driverBase, key);
        if(!userResult.success()){
            return DubboResult.newFailure(userResult.getCode(), userResult.getMessage());
        }
        UserResponseDto user = userResult.getObject();
        RobotExtInfoDto robot = user.transferToExtRobotDto();
        //存用户信息
        JSONObject extInfo = new JSONObject();
        extInfo.put(UIPATH_USER_KEY, user);
        //根据用户会话查询机器状态
        RobotFilter filter = new RobotFilter();
        filter.setUserName(robot.getName());
        DubboResult<ArrayList<SessionResponseDto>> sessionResult = UiPathService.getSessions(driverBase, filter);
        if(sessionResult.success()){
            List<SessionResponseDto> sessions = sessionResult.getObject();
            if(sessions.size() == 1){
                SessionResponseDto session = sessions.get(0);
                //存用户会话信息
                extInfo.put(UIPATH_USER_SESSION_KEY, session);
                if(session.isUnresponsive()){
                    robot.setState(RobotState.Unresponsive.name());
                } else {
                    String trustedState = this.doubleCheckRobotState(driverBase, sessions.get(0).getState(), user.getUserName());
                    robot.setState(trustedState);
                }
                //查询许可类型及状态
                if(user.isMayHaveRobotSession()){
                    //前台
                    robot.setType(RobotType.Attended.name());
                    initAttendedRobotLicense(robot, user);
                } else if(user.isMayHaveUnattendedSession()){
                    //后台
                    robot.setType(RobotType.Unattended.name());
                    initUnattendedRobotLicense(driverBase, robot, session, extInfo);
                }
            } else {
                robot.setState(RobotState.Unknown.name());
                log.error("RobotName={}查询到的用户会话为空或不唯一", robot.getName());
            }
        }
        robot.setExtInfo(extInfo);
        return DubboResult.newSuccess(robot);
    }

    private String doubleCheckRobotState(DriverBase driverBase, String originState, String userName){
        if(!RobotState.Busy.name().equals(originState)){
            return originState;
        }
        //查询当前运行的Job中是否关联此用户判断是否是真的Busy
        JobFilter filter = new JobFilter();
        filter.setState(TaieJobState.Running.name());
        DubboResult<ArrayList<JobResponseDto>> runningJobsResult = UiPathService.queryJobs(driverBase, filter);
        if(!runningJobsResult.success() || CollectionUtils.isEmpty(runningJobsResult.getObject())){
            return RobotState.Available.name();
        }
        ArrayList<JobResponseDto> runningJobs = runningJobsResult.getObject();
        List<JobResponseDto> filteredJobs = runningJobs.stream().filter(job -> job.getRobot().getName().contains(userName)).collect(Collectors.toList());
        //为空表示假忙
        return CollectionUtils.isEmpty(filteredJobs) ? RobotState.Available.name() : RobotState.Busy.name();
    }

    private void initAttendedRobotLicense(RobotDto robot, UserResponseDto user){
        AttendedRobotDto attendedRobotInfo = user.getAttendedRobotDto();
        robot.setLicenseType(attendedRobotInfo.getRobotType());
        //MayHaveRobotSession = true时默认有许可,许可数量充足且机器人为已连接状态时会自动获取许可
        robot.setLicensed(true);
    }

    private void initUnattendedRobotLicense(DriverBase driverBase, RobotExtInfoDto robot, SessionResponseDto session, JSONObject extInfo){
        String machineId = String.valueOf(session.getMachineId());
        //查询机器模板信息，根据模板配置的许可类型判断后台运行时许可类型
        DubboResult<MachineDto> machineResult = UiPathService.queryMachineByKey(driverBase, machineId);
        if(!machineResult.success()){
            log.error("RobotName={}查询关联机器失败原因{}", robot.getName(), machineResult.getMessage());
            return;
        }
        MachineDto machine = machineResult.getObject();
        extInfo.put(UIPATH_MACHINE_KEY, machine);
        if(machine.getNonProductionSlots() > 0){
            robot.setLicenseType(LicenseType.NonProduction.name());
        } else if(machine.getUnattendedSlots() > 0){
            robot.setLicenseType(LicenseType.Unattended.name());
        } else if(machine.getHeadlessSlots() > 0){
            robot.setLicenseType(LicenseType.Headless.name());
        } else if(machine.getTestAutomationSlots() > 0){
            robot.setLicenseType(LicenseType.TestAutomation.name());
        }
        //查询运行时许可信息判断是否赋予了许可(toggleEnable)并存储以提供后续的许可收发
        DubboResult<ArrayList<LicensesRuntimeResponseDto>> licenseRuntimeResult = UiPathService.getLicensesRuntime(driverBase, robot.getLicenseType());
        if(!licenseRuntimeResult.success()){
            log.error("LicenseType={}查询运行许可信息失败原因{}", robot.getLicenseType(), licenseRuntimeResult.getMessage());
            return;
        }
        List<LicensesRuntimeResponseDto> licensesRuntime = licenseRuntimeResult.getObject();
        List<LicensesRuntimeResponseDto> filteredLicensesRuntime = licensesRuntime.stream()
                .filter(license -> session.getMachineId() == license.getMachineId()
                        && session.getMachineName().equals(license.getMachineName())
                        && session.getHostMachineName().equals(license.getHostMachineName()))
                .collect(Collectors.toList());
        if(filteredLicensesRuntime.size() != 1){
            log.error("RobotName={},HostMachineName={},licenseType={}查询到的运行时许可为空或不唯一", robot.getName(), session.getHostMachineName(), robot.getLicenseType());
            return;
        }
        LicensesRuntimeResponseDto licenseRuntime = filteredLicensesRuntime.get(0);
        extInfo.put(UIPATH_RUNTIME_LICENSE_KEY, licenseRuntime);
        robot.setLicensed(licenseRuntime.isLicensed());
        //查询运行时机器会话信息并存储以提供后续后台任务的启动
        DubboResult<ArrayList<MachineSessionRuntimeDto>> runtimeMachineSessions = UiPathService.getRuntimeMachineSessions(driverBase, session.getHostMachineName());
        if(!runtimeMachineSessions.success()){
            log.error("hostMachineName={}查询运行机器会话信息失败原因{}", session.getHostMachineName(), runtimeMachineSessions.getMessage());
            return;
        }
        List<MachineSessionRuntimeDto> machineSessions = runtimeMachineSessions.getObject();
        List<MachineSessionRuntimeDto> filteredMachineSessions = machineSessions.stream()
                .filter(machineSession -> session.getMachineId() == machineSession.getMachineId()
                        && session.getMachineName().equals(machineSession.getMachineName())
                        && robot.getLicenseType().equals(machineSession.getRuntimeType())
                        && !machineSession.isUnresponsive())
                .collect(Collectors.toList());
        if(CollectionUtils.isEmpty(filteredMachineSessions)){
            log.error("RobotName={},HostMachineName={},licenseType={}查询到的有响应的运行时机器会话为空", robot.getName(), session.getHostMachineName(), robot.getLicenseType());
            return;
        }
        MachineSessionRuntimeDto machineSession = filteredMachineSessions.get(0);
        extInfo.put(UIPATH_MACHINE_SESSION_KEY, machineSession);
        robot.setExtInfo(extInfo);
    }

    @Override
    public DubboResult assignRobotToGroup(DriverBase driverBase, String robotKey, String groupKey) {
        OcTenantDetailDto ocTenantInfo;
        Integer robotRoleId;
        try {
            ocTenantInfo = UiPathService.getOcTenantInfo(driverBase);
            robotRoleId = ocTenantInfo.getExtInfo().getInteger("robotRoleId");
        } catch (DriverBusinessException e) {
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, e.getMessage());
        }
        RolesPerFolderDto role = RolesPerFolderDto.builder()
                .folderId(Integer.parseInt(groupKey))
                .roleIds(Lists.newArrayList(robotRoleId))
                .build();
        UserAssignmentDto assignment = UserAssignmentDto.builder()
                .userIds(Lists.newArrayList(Integer.parseInt(robotKey)))
                .rolesPerFolder(Lists.newArrayList(role))
                .build();
        FoldersAssignUserParametersDto assign = FoldersAssignUserParametersDto
                .builder()
                .assignments(assignment)
                .build();
        return UiPathService.assignUserToFolder(driverBase, assign);
    }

    @Override
    public DubboResult removeRobotFromGroup(DriverBase driverBase, String robotKey, String groupKey) {
        return UiPathService.removeUserFromFolder(driverBase, RemoveUserDto.builder().userId(Integer.parseInt(robotKey)).build(), groupKey);
    }

    @Override
    @MethodLog(desc = "发放许可")
    public DubboResult enableLicense(DriverBase driverBase, LicenseDto license) {
        return this.distributeLicense(driverBase, true, license);
    }

    @Override
    @MethodLog(desc = "回收许可")
    public DubboResult disableLicense(DriverBase driverBase, LicenseDto license) {
        return this.distributeLicense(driverBase, false, license);
    }

    private DubboResult distributeLicense(DriverBase driverBase, boolean enable, LicenseDto license){
        DubboResult<RobotExtInfoDto> robotResult = queryRobotExtInfoByKey(driverBase, license.getRobotKey());
        if(!robotResult.success()){
            return robotResult;
        }
        RobotExtInfoDto robot = robotResult.getObject();
        if(Objects.isNull(robot.getExtInfo())){
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "机器人相关信息缺失");
        }
        JSONObject extInfo = robot.getExtInfo();
        if(license.attendedLicense() && Objects.isNull(extInfo.get(UIPATH_USER_KEY))){
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "机器人关联用户信息缺失");
        }
        if(license.unattendedLicense() && (Objects.isNull(extInfo.get(UIPATH_MACHINE_KEY)) || Objects.isNull(extInfo.get(UIPATH_RUNTIME_LICENSE_KEY)))){
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "机器人关联机器及运行许可信息缺失");
        }
        if(license.attendedLicense()){
            UserResponseDto originUser = (UserResponseDto)robot.getExtInfo().get(UIPATH_USER_KEY);
            UserRequestDto updateUser = UserRequestDto.builder()
                    .id(Integer.parseInt(license.getRobotKey()))
                    .name(originUser.getName())
                    .userName(originUser.getUserName())
                    .isActive(true)
                    .rolesList(originUser.getRolesList())
                    .type(originUser.getType())
                    .build();
            if(enable){
                updateUser.setMayHaveRobotSession(true);
                updateUser.setLicenseType(license.getLicenseType());
                updateUser.setAttendedRobotDto(AttendedRobotDto.builder().userName(license.getWhoAmI()).build());
            } else {
                updateUser.setMayHaveRobotSession(false);
            }
            return UiPathService.updateUserByKey(driverBase, license.getRobotKey(), updateUser);
        } else if(license.unattendedLicense()){
            MachineDto machine = (MachineDto)robot.getExtInfo().get(UIPATH_MACHINE_KEY);
            LicensesRuntimeResponseDto licenseRuntime = (LicensesRuntimeResponseDto)robot.getExtInfo().get(UIPATH_RUNTIME_LICENSE_KEY);
            ToggleEnabledRequestDto toggle = ToggleEnabledRequestDto.builder()
                        .robotType(license.getLicenseType())
                        .key(licenseRuntime.getKey())
                        .enabled(enable)
                        .build();
                return UiPathService.toggleEnable(driverBase, machine.getName(), toggle);
        }
        return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "无法识别的许可类型");
    }

    @Override
    public DubboResult<Integer> availableLicenseNum(DriverBase driverBase, String licenseType) {
        DubboResult<LicenseNumDto> licenseResult = UiPathService.getLicense(driverBase);
        if(!licenseResult.success()){
            return DubboResult.newFailure(licenseResult.getCode(), licenseResult.getMessage());
        }
        AllowedAndUsedNumberDto allowed = licenseResult.getObject().getAllowed();
        Integer licenseNum;
        if(Attended.getType().equals(licenseType)){
            licenseNum = allowed.getAttendedNum();
        } else if(Studio.getType().equals(licenseType)){
            licenseNum = allowed.getStudioProNum();
        } else if(StudioX.getType().equals(licenseType)){
            licenseNum = allowed.getStudioXNum();
        } else if(Development.getType().equals(licenseType)){
            licenseNum = allowed.getDevelopmentNum();
        } else if(StudioPro.getType().equals(licenseType)){
            licenseNum = allowed.getStudioProNum();
        } else if(NonProduction.getType().equals(licenseType)){
            licenseNum = allowed.getNonProductionNum();
        } else if(Unattended.getType().equals(licenseType)){
            licenseNum = allowed.getUnattendedNum();
        } else if(Headless.getType().equals(licenseType)){
            licenseNum = allowed.getHeadlessNum();
        } else if(TestAutomation.getType().equals(licenseType)){
            licenseNum = allowed.getTestAutomationNum();
        } else {
            return DubboResult.newFailure(DubboResult.SERVER_EXCEPTION, "不支持的许可类型");
        }
        return DubboResult.newSuccess(licenseNum);
    }

    @Override
    public DubboResult<JobDto> startJob(DriverBase driverBase, StartJobDto start) {
        DubboResult<ProcessReleaseDto> processReleaseResult = UiPathService.queryReleaseByKey(driverBase, start.getProcessReleaseKey());
        if(!processReleaseResult.success()){
            return DubboResult.newFailure(processReleaseResult.getCode(), processReleaseResult.getMessage());
        }
        DubboResult<RobotExtInfoDto> robotResult = queryRobotExtInfoByKey(driverBase, start.getRobotKey());
        if(!robotResult.success()){
            return DubboResult.newFailure(robotResult.getCode(), robotResult.getMessage());
        }
        RobotExtInfoDto robot = robotResult.getObject();
        if(Objects.isNull(robot.getExtInfo())){
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "机器人相关信息缺失");
        }
        JSONObject extInfo = robot.getExtInfo();
        if(Objects.isNull(extInfo.get(UIPATH_USER_SESSION_KEY))){
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "机器人关联全局用户会话信息缺失");
        }
        if(Objects.isNull(extInfo.get(UIPATH_MACHINE_SESSION_KEY))){
            return DubboResult.newFailure(DriverSystemCode.FAIL.getCode(), "机器人关联运行时机器会话信息缺失");
        }
        ProcessReleaseDto release = processReleaseResult.getObject();
        SessionResponseDto session = (SessionResponseDto)robot.getExtInfo().get(UIPATH_USER_SESSION_KEY);
        MachineSessionRuntimeDto machineSession = (MachineSessionRuntimeDto)robot.getExtInfo().get(UIPATH_MACHINE_SESSION_KEY);
        StartProcessDto startProcessDto = StartProcessDto.builder()
                .releaseKey(release.getKey())
                .strategy(JobStrategy.ModernJobsCount.name())
                .robotIds(Lists.newArrayList(session.getRobot().getId()))
                .machineSessionIds(Lists.newArrayList(machineSession.getSessionId()))
                .source(JobSource.Manual.name())
                .inputArguments(start.getInputArguments())
                .jobsCount(1)
                .build();
        JobStartInfoRequestDto startInfo = JobStartInfoRequestDto.builder()
                .startInfo(startProcessDto)
                .build();
        if (StringUtils.isNotBlank(start.getInputArguments())){
            startProcessDto.setInputArguments(start.getInputArguments());
        }
        DubboResult<JobResponseDto> startJobResult = UiPathService.startJob(driverBase, startInfo);
        if(startJobResult.success()){
            JobDto resultRelease = startJobResult.getObject().transferToJobDto();
            return DubboResult.newSuccess(resultRelease);
        } else {
            return DubboResult.newFailure(startJobResult.getCode(), startJobResult.getMessage());
        }
    }

    @Override
    public DubboResult<JobDto> restartJob(DriverBase driverBase, String jobId) {
        DubboResult<JobResponseDto> result = UiPathService.restartJob(driverBase, RestartJobRequestDto.builder().jobId(Integer.parseInt(jobId)).build());
        if(result.success()){
            JobDto job = result.getObject().transferToJobDto();
            return DubboResult.newSuccess(job);
        } else {
            return DubboResult.newFailure(result.getCode(), result.getMessage());
        }
    }

    @Override
    public DubboResult pauseJob(DriverBase driverBase, String jobId) {
        return UiPathService.stopJobByKey(driverBase, jobId, StopJobRequestDto.builder().strategy(StopStrategy.SOFT_STOP.getStrategy()).build());
    }

    @Override
    public DubboResult resumeJob(DriverBase driverBase, String jobId) {
        DubboResult<JobResponseDto> jobResult = UiPathService.queryJobByKey(driverBase, jobId);
        if(!jobResult.success()){
            return DubboResult.newFailure(jobResult.getCode(), jobResult.getMessage());
        }
        JobResponseDto job = jobResult.getObject();
        return UiPathService.resumeJob(driverBase, ResumeJobRequestDto.builder().jobKey(job.getKey()).build());
    }

    @Override
    public DubboResult stopJob(DriverBase driverBase, String jobId) {
        return UiPathService.stopJobByKey(driverBase, jobId, StopJobRequestDto.builder().strategy(StopStrategy.KILL.getStrategy()).build());
    }

    @Override
    public DubboResult stopJobs(DriverBase driverBase, List<String> jobIdList) {
        StopJobRequestDto stop = StopJobRequestDto.builder()
                .strategy(StopStrategy.KILL.getStrategy())
                .jobIds(jobIdList.stream().map(Integer::parseInt).collect(Collectors.toList()))
                .build();
        return UiPathService.stopJobs(driverBase, stop);
    }

    @Override
    public DubboResult<ArrayList<JobDto>> queryJobs(DriverBase driverBase, JobFilter filter) {
        //查询正在运行的任务
        DubboResult<ArrayList<JobResponseDto>> jobsResult = UiPathService.queryJobs(driverBase, filter);
        if(jobsResult.success()){
            List<JobDto> jobs = jobsResult.getObject().stream().map(JobResponseDto::transferToJobDto).collect(Collectors.toList());
            return DubboResult.newSuccess((ArrayList<JobDto>) jobs);
        } else {
            return DubboResult.newFailure(jobsResult.getCode(), jobsResult.getMessage());
        }
    }

    @Override
    public DubboResult<JobDto> queryJobByKey(DriverBase driverBase, String jobId) {
        DubboResult<JobResponseDto> jobResult = UiPathService.queryJobByKey(driverBase, jobId);
        if(jobResult.success()){
            JobDto job = jobResult.getObject().transferToJobDto();
            return DubboResult.newSuccess(job);
        } else {
            return DubboResult.newFailure(jobResult.getCode(), jobResult.getMessage());
        }
    }
}
