package net.fabricmc.fabric.impl.resource.loader;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
import net.fabricmc.fabric.api.resource.v1.ResourceLoader;
import net.fabricmc.loader.api.ModContainer;
import net.minecraft.class_2561;
import net.minecraft.class_2960;
import net.minecraft.class_3262;
import net.minecraft.class_3264;
import net.minecraft.class_3288;
import net.minecraft.class_3302;
import net.minecraft.class_3545;
import net.minecraft.class_7225;
import net.minecraft.class_8614;
import net.minecraft.class_9224;
import net.minecraft.class_9225;
import net.minecraft.class_3288.class_3289;

public class ResourceManagerHelperImpl implements ResourceManagerHelper {
   private static final Map<class_3264, ResourceManagerHelperImpl> registryMap = new HashMap();
   private static final Set<class_3545<class_2561, ModNioResourcePack>> builtinResourcePacks = new HashSet();
   private final ResourceLoader resourceLoader;

   private ResourceManagerHelperImpl(class_3264 type) {
      this.resourceLoader = ResourceLoader.get(type);
   }

   public static ResourceManagerHelperImpl get(class_3264 type) {
      return (ResourceManagerHelperImpl)registryMap.computeIfAbsent(type, ResourceManagerHelperImpl::new);
   }

   public static boolean registerBuiltinResourcePack(class_2960 id, String subPath, ModContainer container, class_2561 displayName, ResourcePackActivationType activationType) {
      List<Path> paths = container.getRootPaths();
      String separator = ((Path)paths.getFirst()).getFileSystem().getSeparator();
      subPath = subPath.replace("/", separator);
      ModNioResourcePack resourcePack = ModNioResourcePack.create(id.toString(), container, subPath, class_3264.field_14188, activationType, false);
      ModNioResourcePack dataPack = ModNioResourcePack.create(id.toString(), container, subPath, class_3264.field_14190, activationType, false);
      if (resourcePack == null && dataPack == null) {
         return false;
      } else {
         if (resourcePack != null) {
            builtinResourcePacks.add(new class_3545(displayName, resourcePack));
         }

         if (dataPack != null) {
            builtinResourcePacks.add(new class_3545(displayName, dataPack));
         }

         return true;
      }
   }

   public static boolean registerBuiltinResourcePack(class_2960 id, String subPath, ModContainer container, ResourcePackActivationType activationType) {
      String var10003 = id.method_12836();
      return registerBuiltinResourcePack(id, subPath, container, class_2561.method_43470(var10003 + "/" + id.method_12832()), activationType);
   }

   public static void registerBuiltinResourcePacks(class_3264 resourceType, Consumer<class_3288> consumer) {
      for(final class_3545<class_2561, ModNioResourcePack> entry : builtinResourcePacks) {
         ModNioResourcePack pack = (ModNioResourcePack)entry.method_15441();
         if (!pack.method_14406(resourceType).isEmpty()) {
            class_9224 info = new class_9224(((ModNioResourcePack)entry.method_15441()).method_14409(), (class_2561)entry.method_15442(), new BuiltinModResourcePackSource(pack.getFabricModMetadata().getName()), ((ModNioResourcePack)entry.method_15441()).method_56929());
            class_9225 info2 = new class_9225(pack.getActivationType() == ResourcePackActivationType.ALWAYS_ENABLED, class_3289.field_14280, false);
            class_3288 profile = class_3288.method_45275(info, new class_3288.class_7680() {
               public class_3262 method_52424(class_9224 var1) {
                  return (class_3262)entry.method_15441();
               }

               public class_3262 method_52425(class_9224 var1, class_3288.class_7679 metadata) {
                  ModNioResourcePack pack = (ModNioResourcePack)entry.method_15441();
                  if (metadata.comp_1584().isEmpty()) {
                     return pack;
                  } else {
                     List<class_3262> overlays = new ArrayList(metadata.comp_1584().size());

                     for(String overlay : metadata.comp_1584()) {
                        overlays.add(pack.createOverlay(overlay));
                     }

                     return new class_8614(pack, overlays);
                  }
               }
            }, resourceType, info2);
            consumer.accept(profile);
         }
      }

   }

   public void registerReloadListener(IdentifiableResourceReloadListener listener) {
      this.resourceLoader.registerReloader(listener.getFabricId(), listener);
      listener.getFabricDependencies().forEach((dependency) -> this.resourceLoader.addReloaderOrdering(dependency, listener.getFabricId()));
   }

   public void registerReloadListener(class_2960 identifier, final Function<class_7225.class_7874, IdentifiableResourceReloadListener> listenerFactory) {
      this.resourceLoader.registerReloader(identifier, new class_3302() {
         public CompletableFuture<Void> method_25931(class_3302.class_11558 store, Executor prepareExecutor, class_3302.class_4045 reloadSynchronizer, Executor applyExecutor) {
            class_7225.class_7874 registries = (class_7225.class_7874)store.method_72362(ResourceLoader.RELOADER_REGISTRY_LOOKUP_KEY);
            class_3302 resourceReloader = (class_3302)listenerFactory.apply(registries);
            return resourceReloader.method_25931(store, prepareExecutor, reloadSynchronizer, applyExecutor);
         }
      });
   }
}
