class AsyncStorageProvisioner {

  public void provision(KubernetesEnvironment k8sEnv, RuntimeIdentity identity)
      throws InfrastructureException {
    if (!parseBoolean(k8sEnv.getAttributes().get(ASYNC_PERSIST_ATTRIBUTE))) {
      return;
    }

    if (!COMMON_STRATEGY.equals(pvcStrategy)) {
      String message =
          format(
              "Workspace configuration not valid: Asynchronous storage available only for 'common' PVC strategy, but got %s",
              pvcStrategy);
      LOG.warn(message);
      k8sEnv.addWarning(new WarningImpl(4200, message));
      throw new InfrastructureException(message);
    }

    if (!isEphemeral(k8sEnv.getAttributes())) {
      String message =
          format(
              "Workspace configuration not valid: Asynchronous storage available only if '%s' attribute set to false",
              ASYNC_PERSIST_ATTRIBUTE);
      LOG.warn(message);
      k8sEnv.addWarning(new WarningImpl(4200, message));
      throw new InfrastructureException(message);
    }

    String namespace = identity.getInfrastructureNamespace();
    String userId = identity.getOwnerId();
    KubernetesClient k8sClient = kubernetesClientFactory.create(identity.getWorkspaceId());
    String configMapName = namespace + ASYNC_STORAGE_CONFIG;

    createPvcIfNotExist(k8sClient, namespace, userId);
    createConfigMapIfNotExist(k8sClient, namespace, configMapName, userId, k8sEnv);
    createAsyncStoragePodIfNotExist(k8sClient, namespace, configMapName, userId);
    createStorageServiceIfNotExist(k8sClient, namespace, userId);
  }

  @Inject public  AsyncStorageProvisioner(
      @Named("che.workspace.sidecar.image_pull_policy") String sidecarImagePullPolicy,
      @Named("che.infra.kubernetes.pvc.quantity") String pvcQuantity,
      @Named("che.infra.kubernetes.async.storage.image") String asyncStorageImage,
      @Named("che.infra.kubernetes.pvc.access_mode") String pvcAccessMode,
      @Named("che.infra.kubernetes.pvc.strategy") String pvcStrategy,
      @Named("che.infra.kubernetes.pvc.name") String pvcName,
      @Named("che.infra.kubernetes.pvc.storage_class_name") String pvcStorageClassName,
      SshManager sshManager,
      KubernetesClientFactory kubernetesClientFactory);

}