Volver al índice

src/main/java/ar/com/companeros/runtime/ResearchConfig.java

package ar.com.companeros.runtime;

import com.google.gson.*;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.IOException;
import java.util.*;

/** Límites y fuentes permitidas de investigación web; el presupuesto sigue siendo global. */
public record ResearchConfig(boolean enabled, int maxRequestsHour, int minAgentIntervalSeconds, Set<String> allowedDomains) {
    public ResearchConfig {
        allowedDomains = Set.copyOf(allowedDomains);
        if (maxRequestsHour < 1 || maxRequestsHour > 12 || minAgentIntervalSeconds < 300 || minAgentIntervalSeconds > 86400
                || allowedDomains.isEmpty() || allowedDomains.size() > 32
                || allowedDomains.stream().anyMatch(domain -> !domain.matches("[a-z0-9][a-z0-9.-]{1,200}\\.[a-z]{2,20}")))
            throw new IllegalArgumentException("Configuración de investigación inválida");
    }
    public static ResearchConfig defaults() {
        return new ResearchConfig(false, 4, 900, Set.of("minecraft.wiki", "createmod.com", "github.com", "modrinth.com", "curseforge.com"));
    }
    public static ResearchConfig load(Path directory) throws IOException {
        Files.createDirectories(directory); Path file = directory.resolve("research.json");
        if (!Files.exists(file)) {
            ResearchConfig initial = defaults(); JsonObject data = new JsonObject(); data.addProperty("schemaVersion", 1);
            data.addProperty("enabled", false); data.addProperty("maxRequestsHour", initial.maxRequestsHour());
            data.addProperty("minAgentIntervalSeconds", initial.minAgentIntervalSeconds());
            JsonArray domains = new JsonArray(); initial.allowedDomains().stream().sorted().forEach(domains::add); data.add("allowedDomains", domains);
            Files.writeString(file, new GsonBuilder().setPrettyPrinting().create().toJson(data) + "\n", StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
        }
        if (Files.isSymbolicLink(file) || Files.size(file) > 8192) throw new IOException("research.json fuera de límite");
        JsonObject data = JsonParser.parseString(Files.readString(file, StandardCharsets.UTF_8)).getAsJsonObject();
        if (!Set.of("schemaVersion", "enabled", "maxRequestsHour", "minAgentIntervalSeconds", "allowedDomains").equals(data.keySet())
                || data.get("schemaVersion").getAsInt() != 1) throw new IOException("Formato de investigación desconocido");
        Set<String> domains = new HashSet<>(); for (JsonElement value : data.getAsJsonArray("allowedDomains")) domains.add(value.getAsString());
        return new ResearchConfig(data.get("enabled").getAsBoolean(), data.get("maxRequestsHour").getAsInt(), data.get("minAgentIntervalSeconds").getAsInt(), domains);
    }
}