package cc.fascinated.bat.service; import cc.fascinated.bat.command.BatCommand; import cc.fascinated.bat.features.Feature; import cc.fascinated.bat.features.base.commands.server.feature.FeatureCommand; import jakarta.annotation.PostConstruct; import lombok.Getter; import lombok.NonNull; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author Fascinated (fascinated7) */ @Service @Getter @Log4j2 @DependsOn("commandService") public class FeatureService { public static FeatureService INSTANCE; private final ApplicationContext context; private final CommandService commandService; /** * The registered features */ private final Map features = new HashMap<>(); @Autowired public FeatureService(@NonNull ApplicationContext context, @NonNull CommandService commandService) { this.context = context; this.commandService = commandService; INSTANCE = this; } @PostConstruct public void init() { context.getBeansOfType(Feature.class) .values() .forEach((feature) -> { features.put(feature.getName().toLowerCase(), feature); }); context.getBeansOfType(BatCommand.class) .values() .forEach((command) -> { if (command.getFeature() == null) { log.error("Command \"{}\" does not belong to a feature, not registering it...", command.getCommandInfo().name()); } }); commandService.registerCommand(context.getBean(FeatureCommand.class)); commandService.registerSlashCommands(); // Register all slash commands } /** * Gets a feature by name * * @param name The name of the feature * @return The feature */ public Feature getFeature(@NonNull String name) { return features.get(name.toLowerCase()); } /** * Gets a feature by class * * @param clazz The class of the feature * @return The feature */ public T getFeature(Class clazz) { Feature feature = features.values().stream().filter(featureClazz -> featureClazz.getClass().equals(clazz)).findFirst().orElse(null); return clazz.cast(feature); } /** * Checks if a feature is registered * * @param name The name of the feature * @return Whether the feature is registered */ public boolean isFeature(@NonNull String name) { return features.containsKey(name.toLowerCase()); } /** * Gets the features sorted by name and status * * @return The features sorted */ public List getFeaturesSorted() { return features.values().stream().sorted((feature1, feature2) -> feature1.getName().compareToIgnoreCase(feature2.getName())).toList(); } }