package jetbrains.mps.ide.actions;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import jetbrains.mps.workbench.action.BaseAction;
import javax.swing.Icon;
import jetbrains.mps.workbench.action.ActionAccess;
import com.intellij.openapi.actionSystem.AnActionEvent;
import java.util.Map;
import jetbrains.mps.project.MPSProject;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.mps.openapi.module.SRepository;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import java.util.List;
import org.jetbrains.mps.openapi.module.SModuleReference;
import jetbrains.mps.internal.collections.runtime.Sequence;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.project.AbstractModule;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;

@GeneratedClass(node = "r:00000000-0000-4000-0000-011c895904a4(jetbrains.mps.ide.actions)/2533953941693774358", model = "r:00000000-0000-4000-0000-011c895904a4(jetbrains.mps.ide.actions)")
public class ForceSaveAll_Action extends BaseAction {
  private static final Icon ICON = null;

  public ForceSaveAll_Action() {
    super("Force Save All", "Updates all models' and modules' files", ICON);
    this.setIsAlwaysVisible(false);
    this.setActionAccess(ActionAccess.NONE);
    updateInBackground(true);
  }
  @Override
  public boolean isDumbAware() {
    return true;
  }
  @Override
  protected boolean collectActionData(AnActionEvent event, final Map<String, Object> _params) {
    if (!(super.collectActionData(event, _params))) {
      return false;
    }
    {
      MPSProject p = event.getData(MPSCommonDataKeys.MPS_PROJECT);
      if (p == null) {
        return false;
      }
    }
    {
      Project p = event.getData(CommonDataKeys.PROJECT);
      if (p == null) {
        return false;
      }
    }
    return true;
  }
  @Override
  public void doExecute(@NotNull final AnActionEvent event, final Map<String, Object> _params) {
    ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
      ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator();
      pi.setIndeterminate(false);

      final SRepository repo = event.getData(MPSCommonDataKeys.MPS_PROJECT).getRepository();
      final Wrappers._T<List<SModuleReference>> moduleRefs = new Wrappers._T<List<SModuleReference>>();
      repo.getModelAccess().runReadAction(() -> moduleRefs.value = Sequence.fromIterable((Iterable<SModule>) event.getData(MPSCommonDataKeys.MPS_PROJECT).getProjectModulesWithGenerators()).ofType(AbstractModule.class).select((it) -> it.getModuleReference()).toList());

      int saving = 1;
      for (final SModuleReference moduleRef : ListSequence.fromList(moduleRefs.value)) {
        pi.setFraction(1.0 * saving / ListSequence.fromList(moduleRefs.value).count());
        repo.getModelAccess().runReadAction(() -> {
          AbstractModule module = (AbstractModule) moduleRef.resolve(repo);
          if (module == null) {
            return;
          }
          ProgressManager.progress2("Saving: " + module.getModuleName());
        });
        ApplicationManager.getApplication().invokeAndWait(() -> repo.getModelAccess().runWriteAction(() -> {
          AbstractModule module = (AbstractModule) moduleRef.resolve(repo);
          if (module == null) {
            return;
          }
          module.forceSaveRecursively();
        }), ModalityState.defaultModalityState());
        saving++;
      }
    }, "Saving...", false, event.getData(CommonDataKeys.PROJECT));
  }
  private Iterable<SModule> getModules(final AnActionEvent event) {
    return (Iterable<SModule>) event.getData(MPSCommonDataKeys.MPS_PROJECT).getProjectModulesWithGenerators();
  }
}
