/*
 * Copyright 2000-2011 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.util.continuation;

import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.CalledInAwt;
import com.intellij.openapi.vcs.changes.BackgroundFromStartOption;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author irengrig
 *         Date: 4/7/11
 *         Time: 2:46 PM
 */
public class SeparatePiecesRunner extends GeneralRunner {
  private final AtomicReference<TaskWrapper> myCurrentWrapper;

  public SeparatePiecesRunner(Project project, boolean cancellable) {
    super(project, cancellable);
    myCurrentWrapper = new AtomicReference<TaskWrapper>();
  }

  @CalledInAwt
  public void ping() {
    clearSuspend();
    final Application application = ApplicationManager.getApplication();
    if (! application.isDispatchThread()) {
      Runnable command = new Runnable() {
        public void run() {
          pingImpl();
        }
      };
      SwingUtilities.invokeLater(command);
    } else {
      pingImpl();
    }
  }

  @CalledInAwt
  private void pingImpl() {
    while (true) {
      myCurrentWrapper.set(null);
      // stop if project is being disposed
      if (!myProject.isDefault() && !myProject.isOpen()) return;
      if (getSuspendFlag()) return;
      final TaskDescriptor current = getNextMatching();
      if (current == null) {
        return;
      }

      if (Where.AWT.equals(current.getWhere())) {
        setIndicator(null);
        try {
          current.run(this);
        }
        catch (RuntimeException th) {
          handleException(th, true);
        }
      }
      else {
        final TaskWrapper task = new TaskWrapper(myProject, current.getName(), myCancellable, current);
        myCurrentWrapper.set(task);
        if (ApplicationManager.getApplication().isUnitTestMode()) {
          setIndicator(new EmptyProgressIndicator());
        }
        else {
          setIndicator(new BackgroundableProcessIndicator(task));
        }
        ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, getIndicator());
        return;
      }
    }
  }

  @Override
  public void suspend() {
    super.suspend();
    final TaskWrapper wrapper = myCurrentWrapper.get();
    if (wrapper != null){
      wrapper.mySuspended = true;
    }
  }

  class TaskWrapper extends ModalityIgnorantBackgroundableTask {
    private final TaskDescriptor myTaskDescriptor;
    private volatile boolean mySuspended;

    TaskWrapper(@Nullable Project project,
                       @NotNull String title,
                       boolean canBeCancelled,
                       TaskDescriptor taskDescriptor) {
      super(project, title, canBeCancelled, BackgroundFromStartOption.getInstance());
      myTaskDescriptor = taskDescriptor;
      mySuspended = false;
    }

    @Override
    protected void doInAwtIfFail(Exception e) {
      doInAwtIfCancel();
    }

    @Override
    protected void doInAwtIfCancel() {
      onCancel();
    }

    @Override
    protected void doInAwtIfSuccess() {
      if (! mySuspended) {
        ping();
      }
    }

    @Override
    protected void runImpl(@NotNull ProgressIndicator indicator) {
      myTaskDescriptor.run(SeparatePiecesRunner.this);
    }
  }
}
