// Path: app/src/main/java/ultimategdbot/service/CommandPermissionUpdater.java
// @RdiService
// public final class CommandPermissionUpdater {
// 
//     private final long applicationId;
//     private final List<UltimateGDBotConfig.CommandPermission> permissions;
//     private final ApplicationService appService;
//     private final Long guildId;
//     private final Mono<Void> onCommandsDeployed;
// 
//     @RdiFactory
//     public CommandPermissionUpdater(ConfigContainer configContainer, ApplicationInfo applicationInfo,
//                                     GatewayDiscordClient gateway, InteractionService interactionService) {
//         this.applicationId = applicationInfo.getId().asLong();
//         this.permissions = configContainer.get(UltimateGDBotConfig.class).commandPermissions();
//         this.appService = gateway.rest().getApplicationService();
//         this.guildId = configContainer.get(InteractionConfig.class).applicationCommandsGuildId().orElse(null);
//         this.onCommandsDeployed = interactionService.onCommandsDeployed();
//     }
// 
//     public Mono<Void> run() {
//         return onCommandsDeployed
//                 .thenMany(guildId == null ?
//                         appService.getGlobalApplicationCommands(applicationId) :
//                         appService.getGuildApplicationCommands(applicationId, guildId))
//                 .collectMap(ApplicationCommandData::name, ApplicationCommandData::id)
//                 .flatMapMany(commandIdsByName -> Flux.fromStream(permissions.stream()
//                         .collect(groupingBy(UltimateGDBotConfig.CommandPermission::guildId))
//                         .entrySet()
//                         .stream()
//                         .map(entry -> updatePermissions(commandIdsByName, entry.getKey(), entry.getValue()))))
//                 .flatMap(Function.identity())
//                 .then();
//     }
// 
//     private Mono<Void> updatePermissions(Map<String, String> commandIdsByName, long guildId,
//                                          List<UltimateGDBotConfig.CommandPermission> permissions) {
//         final var payload = permissions.stream()
//                 .collect(groupingBy(UltimateGDBotConfig.CommandPermission::name))
//                 .entrySet()
//                 .stream()
//                 .map(byCommandName -> (PartialGuildApplicationCommandPermissionsData)
//                         PartialGuildApplicationCommandPermissionsData.builder()
//                                 .id(commandIdsByName.computeIfAbsent(byCommandName.getKey(), k -> {
//                                     throw new IllegalStateException(
//                                             "Command name '" + byCommandName.getKey() + "' not found");
//                                 }))
//                                 .addAllPermissions(byCommandName.getValue().stream()
//                                         .map(perm -> ApplicationCommandPermissionsData.builder()
//                                                 .id(perm.roleId())
//                                                 .type(1)
//                                                 .permission(true)
//                                                 .build())
//                                         .collect(toUnmodifiableList()))
//                                 .build())
//                 .collect(toUnmodifiableList());
//         return appService.bulkModifyApplicationCommandPermissions(applicationId, guildId, payload).then();
//     }
// }
// 
// Path: app/src/main/java/ultimategdbot/service/ExternalServices.java
// public final class ExternalServices {
// 
//     private static final Logger LOGGER = Loggers.getLogger(ExternalServices.class);
// 
//     private ExternalServices() {
//         throw new AssertionError();
//     }
// 
//     public static Mono<ApplicationInfo> applicationInfo(GatewayDiscordClient gateway) {
//         return gateway.getApplicationInfo();
//     }
// 
//     public static Mono<GDClient> gdClient(ConfigContainer configContainer) {
//         var config = configContainer.get(UltimateGDBotConfig.class).gd().client();
//         return GDClient.create()
//                 .withRouter(GDRouter.builder()
//                         .setBaseUrl(config.host())
//                         .setRequestTimeout(config.requestTimeoutSeconds() > 0
//                                 ? Duration.ofSeconds(config.requestTimeoutSeconds()) : null)
//                         .setRequestLimiter(config.requestLimiter()
//                                 .map(l -> RequestLimiter.of(l.limit(), Duration.ofSeconds(l.intervalSeconds())))
//                                 .orElseGet(RequestLimiter::none))
//                         .build())
//                 .withCache(GDCache.caffeine(c -> c.expireAfterAccess(Duration.ofSeconds(config.cacheTtlSeconds()))))
//                 .login(config.username(), config.password())
//                 .doOnNext(client -> LOGGER.debug("Successfully logged into GD account " + config.username()));
//     }
// 
//     public static Mono<SpriteFactory> spriteFactory() {
//         return Mono.fromCallable(SpriteFactory::create)
//                 .subscribeOn(Schedulers.boundedElastic())
//                 .onErrorMap(e -> new RuntimeException("An error occurred when loading the GD icons sprite factory", e));
//     }
// }


import botrino.api.config.ConfigContainer;
import botrino.api.extension.BotrinoExtension;
import com.github.alex1304.rdi.config.ServiceDescriptor;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.entity.ApplicationInfo;
import jdash.client.GDClient;
import jdash.graphics.SpriteFactory;
import reactor.core.publisher.Mono;
import ultimategdbot.service.CommandPermissionUpdater;
import ultimategdbot.service.ExternalServices;
import java.util.Objects;
import java.util.Set;
import static com.github.alex1304.rdi.ServiceReference.ofType;
import static com.github.alex1304.rdi.config.FactoryMethod.externalStaticFactory;
import static com.github.alex1304.rdi.config.Injectable.ref;
package ultimategdbot.framework;




public final class UltimateGDBotExtension implements BotrinoExtension {

    private CommandPermissionUpdater commandPermissionUpdater;

    @Override
    public void onClassDiscovered(Class<?> clazz) {
    }

    @Override
    public void onServiceCreated(Object serviceInstance) {
        if (serviceInstance instanceof CommandPermissionUpdater) {
            this.commandPermissionUpdater = (CommandPermissionUpdater) serviceInstance;
        }
    }

    @Override
    public Set<ServiceDescriptor> provideExtraServices() {
        return Set.of(
                ServiceDescriptor.builder(ofType(ApplicationInfo.class))
// Path: app/src/main/java/ultimategdbot/service/CommandPermissionUpdater.java
// @RdiService
// public final class CommandPermissionUpdater {
// 
//     private final long applicationId;
//     private final List<UltimateGDBotConfig.CommandPermission> permissions;
//     private final ApplicationService appService;
//     private final Long guildId;
//     private final Mono<Void> onCommandsDeployed;
// 
//     @RdiFactory
//     public CommandPermissionUpdater(ConfigContainer configContainer, ApplicationInfo applicationInfo,
//                                     GatewayDiscordClient gateway, InteractionService interactionService) {
//         this.applicationId = applicationInfo.getId().asLong();
//         this.permissions = configContainer.get(UltimateGDBotConfig.class).commandPermissions();
//         this.appService = gateway.rest().getApplicationService();
//         this.guildId = configContainer.get(InteractionConfig.class).applicationCommandsGuildId().orElse(null);
//         this.onCommandsDeployed = interactionService.onCommandsDeployed();
//     }
// 
//     public Mono<Void> run() {
//         return onCommandsDeployed
//                 .thenMany(guildId == null ?
//                         appService.getGlobalApplicationCommands(applicationId) :
//                         appService.getGuildApplicationCommands(applicationId, guildId))
//                 .collectMap(ApplicationCommandData::name, ApplicationCommandData::id)
//                 .flatMapMany(commandIdsByName -> Flux.fromStream(permissions.stream()
//                         .collect(groupingBy(UltimateGDBotConfig.CommandPermission::guildId))
//                         .entrySet()
//                         .stream()
//                         .map(entry -> updatePermissions(commandIdsByName, entry.getKey(), entry.getValue()))))
//                 .flatMap(Function.identity())
//                 .then();
//     }
// 
//     private Mono<Void> updatePermissions(Map<String, String> commandIdsByName, long guildId,
//                                          List<UltimateGDBotConfig.CommandPermission> permissions) {
//         final var payload = permissions.stream()
//                 .collect(groupingBy(UltimateGDBotConfig.CommandPermission::name))
//                 .entrySet()
//                 .stream()
//                 .map(byCommandName -> (PartialGuildApplicationCommandPermissionsData)
//                         PartialGuildApplicationCommandPermissionsData.builder()
//                                 .id(commandIdsByName.computeIfAbsent(byCommandName.getKey(), k -> {
//                                     throw new IllegalStateException(
//                                             "Command name '" + byCommandName.getKey() + "' not found");
//                                 }))
//                                 .addAllPermissions(byCommandName.getValue().stream()
//                                         .map(perm -> ApplicationCommandPermissionsData.builder()
//                                                 .id(perm.roleId())
//                                                 .type(1)
//                                                 .permission(true)
//                                                 .build())
//                                         .collect(toUnmodifiableList()))
//                                 .build())
//                 .collect(toUnmodifiableList());
//         return appService.bulkModifyApplicationCommandPermissions(applicationId, guildId, payload).then();
//     }
// }
// 
// Path: app/src/main/java/ultimategdbot/service/ExternalServices.java
// public final class ExternalServices {
// 
//     private static final Logger LOGGER = Loggers.getLogger(ExternalServices.class);
// 
//     private ExternalServices() {
//         throw new AssertionError();
//     }
// 
//     public static Mono<ApplicationInfo> applicationInfo(GatewayDiscordClient gateway) {
//         return gateway.getApplicationInfo();
//     }
// 
//     public static Mono<GDClient> gdClient(ConfigContainer configContainer) {
//         var config = configContainer.get(UltimateGDBotConfig.class).gd().client();
//         return GDClient.create()
//                 .withRouter(GDRouter.builder()
//                         .setBaseUrl(config.host())
//                         .setRequestTimeout(config.requestTimeoutSeconds() > 0
//                                 ? Duration.ofSeconds(config.requestTimeoutSeconds()) : null)
//                         .setRequestLimiter(config.requestLimiter()
//                                 .map(l -> RequestLimiter.of(l.limit(), Duration.ofSeconds(l.intervalSeconds())))
//                                 .orElseGet(RequestLimiter::none))
//                         .build())
//                 .withCache(GDCache.caffeine(c -> c.expireAfterAccess(Duration.ofSeconds(config.cacheTtlSeconds()))))
//                 .login(config.username(), config.password())
//                 .doOnNext(client -> LOGGER.debug("Successfully logged into GD account " + config.username()));
//     }
// 
//     public static Mono<SpriteFactory> spriteFactory() {
//         return Mono.fromCallable(SpriteFactory::create)
//                 .subscribeOn(Schedulers.boundedElastic())
//                 .onErrorMap(e -> new RuntimeException("An error occurred when loading the GD icons sprite factory", e));
//     }
// }


// Path: app/src/main/java/ultimategdbot/framework/UltimateGDBotExtension.java
import botrino.api.config.ConfigContainer;
import botrino.api.extension.BotrinoExtension;
import com.github.alex1304.rdi.config.ServiceDescriptor;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.entity.ApplicationInfo;
import jdash.client.GDClient;
import jdash.graphics.SpriteFactory;
import reactor.core.publisher.Mono;
import ultimategdbot.service.CommandPermissionUpdater;
import ultimategdbot.service.ExternalServices;
import java.util.Objects;
import java.util.Set;
import static com.github.alex1304.rdi.ServiceReference.ofType;
import static com.github.alex1304.rdi.config.FactoryMethod.externalStaticFactory;
import static com.github.alex1304.rdi.config.Injectable.ref;

package ultimategdbot.framework;




public final class UltimateGDBotExtension implements BotrinoExtension {

    private CommandPermissionUpdater commandPermissionUpdater;

    @Override
    public void onClassDiscovered(Class<?> clazz) {
    }

    @Override
    public void onServiceCreated(Object serviceInstance) {
        if (serviceInstance instanceof CommandPermissionUpdater) {
            this.commandPermissionUpdater = (CommandPermissionUpdater) serviceInstance;
        }
    }

    @Override
    public Set<ServiceDescriptor> provideExtraServices() {
        return Set.of(
                ServiceDescriptor.builder(ofType(ApplicationInfo.class))
                        .setFactoryMethod(externalStaticFactory(ExternalServices.class, "applicationInfo",