package com.airlock.iam.admin.infrastructure.service.ume;

import com.airlock.iam.admin.api.infrastructure.UserManagementExtension;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.elog.api.LogTypes;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

@SuppressFBWarnings({"NP_LOAD_OF_KNOWN_NULL_VALUE", "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public class UserManagementExtensionClasspathLoader {
   private static final ELogger LOG = ELoggerFactory.getLogger(UserManagementExtensionClasspathLoader.class);
   private final Provider<UserManagementExtensionCache> cache;
   private final Provider<UserManagementExtensionLoader> loader;

   @Inject
   public UserManagementExtensionClasspathLoader(Provider<UserManagementExtensionCache> cache, Provider<UserManagementExtensionLoader> loader) {
      this.cache = cache;
      this.loader = loader;
   }

   public Optional<UserManagementExtensionResourceContent> loadUserManagementExtensions() {
      if (((UserManagementExtensionCache)this.cache.get()).getCacheState().equals(UserManagementExtensionCache.CacheState.NEW)) {
         String content = ((UserManagementExtensionLoader)this.loader.get())
            .loadUserManagementExtensions()
            .stream()
            .filter(ume -> ume.resourcePath() != null)
            .map(this::tryGetResource)
            .flatMap(Optional::stream)
            .reduce("", String::concat)
            .stripTrailing();
         ((UserManagementExtensionCache)this.cache.get())
            .init(content.isBlank() ? Optional.empty() : Optional.of(new UserManagementExtensionResourceContent(content)));
      }

      return ((UserManagementExtensionCache)this.cache.get()).getResource();
   }

   private Optional<String> tryGetResource(UserManagementExtension userManagementExtension) {
      try (InputStream inputStream = userManagementExtension.getClass().getResourceAsStream(userManagementExtension.resourcePath())) {
         if (inputStream != null) {
            return Optional.of(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8).concat("\n"));
         }

         LOG.error(LogTypes.RESOURCE_NOT_FOUND, "Failed to load JavaScript resource from Classpath: No resource found in path");
      } catch (IOException e) {
         LOG.error(LogTypes.RESOURCE_NOT_FOUND, "Failed to load JavaScript resource from Classpath", e);
      }

      return Optional.empty();
   }
}
