/* (C) 2025 Linnea Gräf - Licensed to everyone under the BSD 3 Clause License */ package moe.nea.prickly.config; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.jspecify.annotations.Nullable; @Slf4j public class ConfigCompat { public static final Path ENV_FILE = Path.of(".env").toAbsolutePath(); @SuppressWarnings({"unchecked", "rawtypes"}) private static Map loadDotenv() { var properties = new Properties(); if (!Files.exists(ENV_FILE)) { log.info("no .env file found at {}", ENV_FILE); } else { try (var reader = Files.newBufferedReader(ENV_FILE, StandardCharsets.UTF_8)) { properties.load(reader); log.info("loaded environment from {} ({} entries)", ENV_FILE, properties.size()); } catch (IOException e) { log.error("could not read .env file at {}", ENV_FILE, e); } } return (Map) properties; } public static Map DOTENV_FALLBACK = Collections.unmodifiableMap(loadDotenv()); public static NavigableMap ENV; static { var env = new TreeMap(); env.putAll(DOTENV_FALLBACK); env.putAll(System.getenv()); ENV = Collections.unmodifiableNavigableMap(env); } public static @Nullable String getEnv(String key) { return ENV.get(key); } public static Map getAllEnvStartingWith(String prefix) { return ENV.subMap(prefix + "_", prefix + (char) ((int) '_' + 1)); } public static Set getAllDirectChildren(String prefix) { int start = prefix.length() + 1; return getAllEnvStartingWith(prefix).keySet().stream() .map(it -> { int nextUnderscore = it.indexOf('_', start); if (nextUnderscore < 0) return it.substring(start); else return it.substring(start, nextUnderscore); }) .collect(Collectors.toSet()); } }