package jetbrains.mps.ide.make.actions;

/*Generated by MPS */

import com.intellij.openapi.progress.Task;
import jetbrains.mps.project.MPSProject;
import java.util.Set;
import org.jetbrains.mps.openapi.module.SModule;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.LinkedHashSet;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.progress.ProgressIndicator;
import org.jetbrains.mps.openapi.util.ProgressMonitor;
import jetbrains.mps.progress.ProgressMonitorAdapter;
import jetbrains.mps.ide.messages.DefaultMessageHandler;
import jetbrains.mps.make.ModuleMaker;
import jetbrains.mps.messages.MessageKind;
import jetbrains.mps.compiler.JavaCompilerOptionsComponent;
import jetbrains.mps.make.MPSCompilationResult;
import jetbrains.mps.messages.Message;
import jetbrains.mps.classloading.ClassLoaderManager;

public class DefaultMakeTask extends Task.Modal {
  private final MPSProject myProject;
  private boolean needClean;
  private Set<SModule> modules = SetSequence.fromSet(new LinkedHashSet<SModule>());

  public DefaultMakeTask(MPSProject mpsProject, String title, Set<SModule> modules, boolean needClean) {
    super(mpsProject.getProject(), title, true);
    this.needClean = needClean;
    SetSequence.fromSet(this.modules).addSequence(SetSequence.fromSet(modules));
    myProject = mpsProject;
  }

  @Override
  public void run(@NotNull ProgressIndicator indicator) {
    final ProgressMonitor monitor = new ProgressMonitorAdapter(indicator);
    monitor.start("", (needClean ? 10 : 9));
    try {
      DefaultMessageHandler mh = new DefaultMessageHandler(getProject());
      final ModuleMaker maker = new ModuleMaker(mh.restrict(MessageKind.ERROR));
      myProject.getModelAccess().runReadAction(() -> {
        if (needClean) {
          maker.clean(modules, monitor.subTask(1));
        }
        maker.options(JavaCompilerOptionsComponent.getInstance().getJavaCompilerOptions(myProject));
        maker.prepare(modules, needClean, monitor.subTask(3));
      });

      final MPSCompilationResult mpsCompilationResult = maker.make(monitor.subTask(4));

      if (mpsCompilationResult.isOk()) {
        mh.handle(Message.info(getClass(), String.format("Compilation of %d modules completed successfully", SetSequence.fromSet(modules).count()), null, null));
      } else if (mpsCompilationResult.isAborted()) {
        mh.handle(Message.info(getClass(), "Compilation aborted", null, null));
      }

      if (mpsCompilationResult.isReloadingNeeded()) {
        mh.handle(Message.info(getClass(), String.format("%d affected modules require re-load", mpsCompilationResult.getAffectedModules().size()), null, null));
        myProject.getComponent(ClassLoaderManager.class).reload(mpsCompilationResult.getAffectedModules(), monitor.subTask(2));
      }
    } finally {
      monitor.done();
    }
  }
}
