class StackOperationService {

    @VisibleForTesting
    FlowIdentifier start(Stack stack, Cluster cluster, boolean updateCluster, User user) {
        FlowIdentifier flowIdentifier = FlowIdentifier.notTriggered();
        environmentService.checkEnvironmentStatus(stack, EnvironmentStatus.startable());
        if (stack.isAvailable() && (cluster == null || cluster.isAvailable())) {
            eventService.fireCloudbreakEvent(stack.getId(), AVAILABLE.name(), STACK_START_IGNORED);
        } else if (isStackStartable(stack) || isClusterStartable(cluster)) {
            Stack startStack = stackUpdater.updateStackStatus(stack.getId(), DetailedStackStatus.START_REQUESTED);
            flowIdentifier = flowManager.triggerStackStart(stack.getId());
            if (updateCluster && cluster != null) {
                clusterOperationService.updateStatus(startStack, StatusRequest.STARTED);
            }
        } else {
            throw NotAllowedStatusUpdate
                    .stack(stack)
                    .to(DetailedStackStatus.START_REQUESTED)
                    .badRequest();
        }
        return flowIdentifier;
    }

}