class RepairInstancesService {

    public OperationStatus repairInstances(String accountId, RepairInstancesRequest request) {
        Stack stack = stackService.getByEnvironmentCrnAndAccountIdWithLists(request.getEnvironmentCrn(), accountId);
        MDCBuilder.buildMdcContext(stack);

        if (request.isForceRepair() && CollectionUtils.isEmpty(request.getInstanceIds())) {
            throw new UnsupportedOperationException("Force repair requires the instance IDs to be provided.");
        }

        Map<String, InstanceStatus> healthMap = request.isForceRepair() ? Collections.emptyMap() : getInstanceHealthMap(accountId, request.getEnvironmentCrn());
        Map<String, InstanceMetaData> allInstancesByInstanceId = getAllInstancesFromStack(stack);
        Map<String, InstanceMetaData> instancesToRepair =
                getInstancesToRepair(healthMap, allInstancesByInstanceId, request.getInstanceIds(), request.isForceRepair(), false);

        Set<InstanceMetaData> remainingGoodInstances =
                getRemainingGoodInstances(allInstancesByInstanceId, instancesToRepair, healthMap, request.isForceRepair());
        Set<InstanceMetaData> remainingBadInstances = getRemainingBadInstances(allInstancesByInstanceId, instancesToRepair, healthMap, request.isForceRepair());
        validate(accountId, stack, remainingGoodInstances, remainingBadInstances, instancesToRepair.values());
        int nodeCount = stack.getInstanceGroups().stream().findFirst().get().getNodeCount();

        List<String> additionalTerminatedInstanceIds = getAdditionalTerminatedInstanceIds(allInstancesByInstanceId.values(), request.getInstanceIds());

        Operation operation = operationService.startOperation(accountId, OperationType.REPAIR, Set.of(stack.getEnvironmentCrn()), Collections.emptySet());
        if (operation.getStatus() == OperationState.RUNNING) {
            stackUpdater.updateStackStatus(stack.getId(), DetailedStackStatus.REPAIR_REQUESTED, "Repair requested");
            flowManager.notify(FlowChainTriggers.REPAIR_TRIGGER_EVENT, new RepairEvent(FlowChainTriggers.REPAIR_TRIGGER_EVENT, stack.getId(),
                    operation.getOperationId(), nodeCount, instancesToRepair.keySet().stream().collect(Collectors.toList()), additionalTerminatedInstanceIds));
        }
        return operationToOperationStatusConverter.convert(operation);
    }

}