package io.gitlab.jfronny.inceptum.launcher.system.instance; import gsoncompile.extensions.io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta.GC_InstanceMeta; import io.gitlab.jfronny.commons.io.JFiles; import io.gitlab.jfronny.commons.throwable.ThrowingConsumer; import io.gitlab.jfronny.inceptum.common.MetaHolder; import io.gitlab.jfronny.inceptum.common.Utils; import io.gitlab.jfronny.inceptum.launcher.model.inceptum.InstanceMeta; import io.gitlab.jfronny.inceptum.launcher.util.FileBackedRef; import java.io.Closeable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; public class InstanceList { private static final Map metas = new LinkedHashMap<>(); public static final String INSTANCE_CONFIG_NAME = "instance.json"; public static void reset() { synchronized (metas) { for (var entry : metas.entrySet()) { try { entry.value.close(); } catch (IOException e) { Utils.LOGGER.error("Could not close reference to instance meta", e); } } metas.clear(); } } public static Set ordered() throws IOException { TreeSet set = new TreeSet<>(); forEach(set::add); return set.descendingSet(); } public static void forEach(ThrowingConsumer target) throws IOException, TEx { Objects.requireNonNull(target); if (!Files.exists(MetaHolder.INSTANCE_DIR)) Files.createDirectories(MetaHolder.INSTANCE_DIR); try { JFiles.listTo(MetaHolder.INSTANCE_DIR, path -> { if (!isInstance(path)) return; target.accept(read(path)); }); } catch (Exception e) { //noinspection unchecked throw (TEx) e; } } public static boolean isEmpty() throws IOException { if (!Files.exists(MetaHolder.INSTANCE_DIR)) return true; return JFiles.list(MetaHolder.INSTANCE_DIR, InstanceList::isInstance).isEmpty; } public static Instance read(Path instancePath) throws IOException { Objects.requireNonNull(instancePath); synchronized (metas) { if (!metas.containsKey(instancePath)) { metas[instancePath] = new IEntry( instancePath, new FileBackedRef<>(instancePath.resolve(INSTANCE_CONFIG_NAME), GC_InstanceMeta::read) ); } return metas[instancePath].toPub(); } } private static boolean isInstance(Path path) { return Files.isDirectory(path) && Files.exists(path.resolve(INSTANCE_CONFIG_NAME)); } private record IEntry(Path path, FileBackedRef meta) implements Closeable { @Override public String toString() { return path.fileName.toString(); } public Instance toPub() throws IOException { return new Instance(path, meta.get()); } @Override public void close() throws IOException { meta.close(); } } }