package com.narrowtux.fmm.io.tasks;
import com.narrowtux.fmm.model.Datastore;
import com.narrowtux.fmm.io.FileDeleter;
import com.narrowtux.fmm.model.ModReference;
import com.narrowtux.fmm.model.Modpack;
import javafx.application.Platform;
import javafx.concurrent.Task;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Consumer;
public abstract class ModsInstaller extends Task<Process> {
private Optional<Runnable> onDone;
private Optional<Consumer<Exception>> onError;
protected abstract Collection<ModReference> getMods();
protected abstract Process startFactorio() throws IOException;
@Override
protected Process call() throws Exception {
updateTitle("Installing mods and launching factorio");
Process ret = null;
try {
int steps = 5 + getMods().size();
int step = 0;
updateProgress(step, steps);
Path tmp = null;
if (Files.exists(Datastore.getInstance().getModDir())) {
updateMessage("Backing up old mods directory");
tmp = Datastore.getInstance().getDataDir().resolve("tmp");
if (Files.exists(tmp)) {
Files.walkFileTree(tmp, new FileDeleter());
}
Files.move(Datastore.getInstance().getModDir(), tmp);
updateProgress(++step, steps);
}
updateProgress(++step, steps);
updateMessage("Creating new mods directory");
Files.createDirectory(Datastore.getInstance().getModDir());
updateMessage("Writing mod-list.json");
Modpack.writeModList(Datastore.getInstance().getModDir().resolve("mod-list.json"), false, getMods().toArray(new ModReference[getMods().size()]));
updateProgress(++step, steps);
for (ModReference mod : getMods()) {
updateMessage("Installing mod " + mod.getMod().toSimpleString());
Files.copy(mod.getMod().getPath(), Datastore.getInstance().getModDir().resolve(mod.getMod().getPath().getFileName()));
updateProgress(++step, steps);
}
updateMessage("Removing backup");
if (tmp != null) {
Files.walkFileTree(tmp, new FileDeleter());
updateProgress(++step, steps);
}
updateMessage("Launching factorio");
ret = startFactorio();
updateProgress(++step, steps);
onDone.ifPresent(Platform::runLater);
} catch (IOException e) {
e.printStackTrace();
onError.ifPresent(consumer -> Platform.runLater(() -> consumer.accept(e)));
}
return ret;
}
public Optional<Consumer<Exception>> getOnError() {
return onError;
}
public void setOnError(Consumer<Exception> onError) {
this.onError = Optional.ofNullable(onError);
}
public Optional<Runnable> getOnDone() {
return onDone;
}
public void setOnDone(Runnable onDone) {
this.onDone = Optional.ofNullable(onDone);
}
}