// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.util;

import java.io.IOException;
import com.hypixel.hytale.codec.ExtraInfo;
import java.util.function.Supplier;
import com.hypixel.hytale.sneakythrow.SneakyThrow;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.util.RawJsonReader;
import com.hypixel.hytale.logger.HytaleLogger;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nullable;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import javax.annotation.Nonnull;
import java.nio.file.Path;

public class Config<T>
{
    @Nonnull
    private final Path path;
    private final String name;
    private final BuilderCodec<T> codec;
    @Nullable
    private T config;
    @Nullable
    private CompletableFuture<T> loadingConfig;
    
    public Config(@Nonnull final Path path, final String name, final BuilderCodec<T> codec) {
        this.path = path.resolve(name + ".json");
        this.name = name;
        this.codec = codec;
    }
    
    @Nonnull
    @Deprecated(forRemoval = true)
    public static <T> Config<T> preloadedConfig(@Nonnull final Path path, final String name, final BuilderCodec<T> codec, final T config) {
        final Config<T> c = new Config<T>(path, name, codec);
        c.config = config;
        return c;
    }
    
    @Nonnull
    public CompletableFuture<T> load() {
        if (this.loadingConfig != null) {
            return this.loadingConfig;
        }
        if (!Files.exists(this.path, new LinkOption[0])) {
            this.config = this.codec.getDefaultValue();
            return CompletableFuture.completedFuture(this.config);
        }
        return this.loadingConfig = CompletableFuture.supplyAsync((Supplier<T>)SneakyThrow.sneakySupplier(() -> {
            this.config = RawJsonReader.readSync(this.path, this.codec, HytaleLogger.getLogger());
            this.loadingConfig = null;
            return this.config;
        }));
    }
    
    public T get() {
        if (this.config == null && this.loadingConfig == null) {
            throw new IllegalStateException("Config is not loaded");
        }
        if (this.loadingConfig != null) {
            return this.loadingConfig.join();
        }
        return this.config;
    }
    
    @Nonnull
    public CompletableFuture<Void> save() {
        if (this.config == null && this.loadingConfig == null) {
            throw new IllegalStateException("Config is not loaded");
        }
        if (this.loadingConfig != null) {
            return CompletableFuture.completedFuture((Void)null);
        }
        return BsonUtil.writeDocument(this.path, this.codec.encode(this.config, new ExtraInfo()));
    }
}
