package com.intellij.javascript.karma.server;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class KarmaServerRestarter {
private final AtomicInteger myActiveRunners = new AtomicInteger(0);
private final AtomicBoolean myConfigChanged = new AtomicBoolean(false);
private boolean myRestartRequested = false;
public KarmaServerRestarter(@NotNull File configurationFile, @NotNull Disposable parentDisposable) {
listenForConfigurationFileChanges(configurationFile, parentDisposable);
}
private void listenForConfigurationFileChanges(@NotNull final File configurationFile,
@NotNull final Disposable parentDisposable) {
ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().runWriteAction(() -> {
VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(configurationFile);
if (virtualFile != null && virtualFile.isValid() && !virtualFile.isDirectory()) {
Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
if (document != null && !Disposer.isDisposed(parentDisposable)) {
document.addDocumentListener(new DocumentListener() {
@Override
public void documentChanged(DocumentEvent e) {
myConfigChanged.set(true);
}
}, parentDisposable);
}
}
}), ModalityState.any());
}
public void onRunnerExecutionStarted(@NotNull final OSProcessHandler processHandler) {
myActiveRunners.incrementAndGet();
processHandler.addProcessListener(new ProcessAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
myActiveRunners.decrementAndGet();
processHandler.removeProcessListener(this);
}
});
}
public boolean isRestartRequired() {
return myActiveRunners.get() == 0 && (myRestartRequested || myConfigChanged.get());
}
public void requestRestart() {
myRestartRequested = true;
}
}