package com.hypixel.hytale.procedurallib.json;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class JsonLoader<K extends SeedResource, T> extends Loader<K, T> {
@Nullable
protected final JsonElement json;
public JsonLoader(SeedString<K> seed, Path dataFolder, @Nullable JsonElement json) {
super(seed, dataFolder);
if (json != null && json.isJsonObject() && json.getAsJsonObject().has("File")) {
this.json = this.loadFileConstructor(json.getAsJsonObject().get("File").getAsString());
} else {
this.json = json;
}
}
public boolean has(String name) {
return this.json != null && this.json.isJsonObject() && this.json.getAsJsonObject().has(name);
}
@Nullable
public JsonElement get(String name) {
if (this.json != null && this.json.isJsonObject()) {
JsonElement element = this.json.getAsJsonObject().get(name);
if (element != null && element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
if (object.has("File")) {
element = this.loadFileElem(object.get("File").getAsString());
}
}
return element;
} else {
return null;
}
}
@Nullable
public JsonElement getRaw(String name) {
return this.json != null && this.json.isJsonObject() ? this.json.getAsJsonObject().get(name) : null;
}
protected JsonElement loadFile(@Nonnull String filePath) {
Path file = this.dataFolder.resolve(filePath.replace('.', File.separatorChar) + ".json");
try {
JsonReader reader = new JsonReader(Files.newBufferedReader(file));
JsonElement var4;
try {
var4 = JsonParser.parseReader(reader);
} catch (Throwable var7) {
try {
reader.close();
} catch (Throwable var6) {
var7.addSuppressed(var6);
}
throw var7;
}
reader.close();
return var4;
} catch (Throwable e) {
throw new Error("Error while loading file reference." + file.toString(), e);
}
}
protected JsonElement loadFileElem(@Nonnull String filePath) {
return this.loadFile(filePath);
}
protected JsonElement loadFileConstructor(@Nonnull String filePath) {
return this.loadFile(filePath);
}
@Nonnull
protected JsonObject mustGetObject(@Nonnull String key, @Nullable JsonObject defaultValue) {
return (JsonObject)this.mustGet(key, defaultValue, JsonObject.class, JsonElement::isJsonObject, JsonElement::getAsJsonObject);
}
@Nonnull
protected JsonArray mustGetArray(@Nonnull String key, @Nullable JsonArray defaultValue) {
return (JsonArray)this.mustGet(key, defaultValue, JsonArray.class, JsonElement::isJsonArray, JsonElement::getAsJsonArray);
}
@Nonnull
protected String mustGetString(@Nonnull String key, @Nullable String defaultValue) {
return (String)this.mustGet(key, defaultValue, String.class, JsonLoader::isString, JsonElement::getAsString);
}
@Nonnull
protected Boolean mustGetBool(@Nonnull String key, @Nullable Boolean defaultValue) {
return (Boolean)this.mustGet(key, defaultValue, Boolean.class, JsonLoader::isBoolean, JsonElement::getAsBoolean);
}
@Nonnull
protected Number mustGetNumber(@Nonnull String key, @Nullable Number defaultValue) {
return (Number)this.mustGet(key, defaultValue, Number.class, JsonLoader::isNumber, JsonElement::getAsNumber);
}
protected <V> V mustGet(@Nonnull String key, @Nullable V defaultValue, @Nonnull Class<V> type, @Nonnull Predicate<JsonElement> predicate, @Nonnull Function<JsonElement, V> mapper) {
return (V)mustGet(key, this.get(key), defaultValue, type, predicate, mapper);
}
protected static <V> V mustGet(@Nonnull String key, @Nullable JsonElement element, @Nullable V defaultValue, @Nonnull Class<V> type, @Nonnull Predicate<JsonElement> predicate, @Nonnull Function<JsonElement, V> mapper) {
if (element == null) {
if (defaultValue != null) {
return defaultValue;
} else {
throw error("Missing property '%s'", key);
}
} else if (!predicate.test(element)) {
throw error("Property '%s' must be of type '%s'", key, type.getSimpleName());
} else {
return (V)mapper.apply(element);
}
}
protected static Error error(String format, Object... args) {
return new Error(String.format(format, args));
}
protected static Error error(Throwable parent, String format, Object... args) {
return new Error(String.format(format, args), parent);
}
private static boolean isString(JsonElement element) {
return element.isJsonPrimitive() && element.getAsJsonPrimitive().isString();
}
protected static boolean isNumber(JsonElement element) {
return element.isJsonPrimitive() && element.getAsJsonPrimitive().isNumber();
}
protected static boolean isBoolean(JsonElement element) {
return element.isJsonPrimitive() && element.getAsJsonPrimitive().isBoolean();
}
public interface Constants {
char JSON_FILEPATH_SEPARATOR = '.';
String KEY_FILE = "File";
}
}