package tc.oc.commons.bukkit.configuration;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.util.Vector;
import java.time.Duration;
import tc.oc.commons.core.util.Numbers;
import tc.oc.commons.core.util.TimeUtils;
import tc.oc.minecraft.api.configuration.InvalidConfigurationException;
public abstract class ConfigUtils {
public static <T extends Enum<T>> T getEnum(ConfigurationSection config, String key, Class<T> type, @Nullable T def) {
final String value = config.getString(key);
return value == null ? def : Enum.valueOf(type, value.toUpperCase());
}
public static <T extends Enum<T>> T getEnum(ConfigurationSection config, String key, Class<T> type) {
return getEnum(config, key, type, null);
}
public static @Nullable Duration getDuration(ConfigurationSection config, String key) {
return getDuration(config, key, null);
}
public static Duration getDuration(ConfigurationSection config, String key, Duration def) {
return TimeUtils.parseDuration(config.getString(key), def);
}
public static double getPercentage(ConfigurationSection config, String key, double def) {
double percent = config.getDouble(key, def);
if(percent < 0 || percent > 1) {
throw new IllegalArgumentException("Config value " + key + ": percentage must be between 0 and 1");
}
return percent;
}
public static Vector getVector(ConfigurationSection section, String key, Vector def) {
Object o = section.get(key);
if(o == null) {
return def;
} else if(o instanceof List) {
List v = (List) o;
return new Vector(Numbers.coerce(v.get(0), Double.class, true),
Numbers.coerce(v.get(1), Double.class, true),
Numbers.coerce(v.get(2), Double.class, true));
} else if(o instanceof ConfigurationSection) {
ConfigurationSection v = (ConfigurationSection) o;
return new Vector(v.getDouble("x"), v.getDouble("y"), v.getDouble("z"));
} else {
throw new IllegalArgumentException("Cannot coerce " + o.getClass() + " to vector");
}
}
public static Path getPath(ConfigurationSection section, String key, Path def) {
String value = section.getString(key);
return value == null ? def : Paths.get(value);
}
public static List<Path> getPathList(ConfigurationSection section, String key) {
return Lists.transform(section.getStringList(key), new Function<String, Path>() {
@Override
public Path apply(String path) {
return Paths.get(path);
}
});
}
public static URL getUrl(ConfigurationSection section, String key, URL def) {
String value = section.getString(key);
try {
return value == null ? def : new URL(value);
} catch(MalformedURLException e) {
throw new IllegalArgumentException("Invalid URL format '" + value + "'", e);
}
}
public static <T> List<T> needValueOrList(ConfigurationSection section, String key, Class<T> type) throws InvalidConfigurationException {
final T value = section.getType(key, type);
return value != null ? ImmutableList.of(value)
: section.needList(key, type);
}
public static String needStringOrSectionName(ConfigurationSection section, @Nullable String key, @Nullable String value) throws InvalidConfigurationException {
if(value != null) {
return value;
} else if(key != null) {
return section.needString(key);
} else {
return section.getName();
}
}
private static JsonElement toJson(Object value) {
if(value instanceof ConfigurationSection) {
return toJson((ConfigurationSection) value);
} else if(value instanceof Map) {
return toJson((Map) value);
} else if(value instanceof List) {
return toJson((List) value);
} else if(value instanceof String) {
return new JsonPrimitive((String) value);
} else if(value instanceof Character) {
return new JsonPrimitive((Character) value);
} else if(value instanceof Number) {
return new JsonPrimitive((Number) value);
} else if(value instanceof Boolean) {
return new JsonPrimitive((Boolean) value);
} else if(value == null) {
return JsonNull.INSTANCE;
} else {
throw new IllegalArgumentException("Cannot coerce " + value.getClass().getSimpleName() + " to JSON");
}
}
public static JsonArray toJson(List list) {
JsonArray json = new JsonArray();
for(Object item : list) {
json.add(toJson(item));
}
return json;
}
public static JsonObject toJson(Map<?, ?> map) {
JsonObject json = new JsonObject();
for(Map.Entry<?, ?> entry : map.entrySet()) {
json.add(entry.getKey().toString(), toJson(entry.getValue()));
}
return json;
}
public static JsonObject toJson(ConfigurationSection config) {
JsonObject json = new JsonObject();
for(Map.Entry<String, Object> entry : config.getValues(false).entrySet()) {
json.add(entry.getKey(), toJson(entry.getValue()));
}
return json;
}
}