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

import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.fabricmc.fabric.api.resource.ModResourcePack;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.class_2561;
import net.minecraft.class_3264;
import net.minecraft.class_3285;
import net.minecraft.class_3288;
import net.minecraft.class_5352;
import net.minecraft.class_9224;
import net.minecraft.class_9225;
import net.minecraft.class_3288.class_3289;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;

public class ModResourcePackCreator implements class_3285 {
   public static final String FABRIC = "fabric";
   private static final String PROGRAMMER_ART = "programmer_art";
   private static final String HIGH_CONTRAST = "high_contrast";
   public static final Set<String> POST_CHANGE_HANDLE_REQUIRED = Set.of("fabric", "programmer_art", "high_contrast");
   @VisibleForTesting
   public static final Predicate<Set<String>> BASE_PARENT = (enabled) -> enabled.contains("fabric");
   @VisibleForTesting
   public static final Predicate<Set<String>> PROGRAMMER_ART_PARENT = (enabled) -> enabled.contains("fabric") && enabled.contains("programmer_art");
   @VisibleForTesting
   public static final Predicate<Set<String>> HIGH_CONTRAST_PARENT = (enabled) -> enabled.contains("fabric") && enabled.contains("high_contrast");
   public static final class_5352 RESOURCE_PACK_SOURCE = new class_5352() {
      public class_2561 method_45282(class_2561 packName) {
         return class_2561.method_43469("pack.nameAndSource", new Object[]{packName, class_2561.method_43471("pack.source.fabricmod")});
      }

      public boolean method_45279() {
         return true;
      }
   };
   public static final ModResourcePackCreator CLIENT_RESOURCE_PACK_PROVIDER;
   public static final int MAX_KNOWN_PACKS;
   private final class_3264 type;
   private final class_9225 activationInfo;
   private final boolean forClientDataPackManager;

   public ModResourcePackCreator(class_3264 type) {
      this(type, false);
   }

   protected ModResourcePackCreator(class_3264 type, boolean forClientDataPackManager) {
      this.type = type;
      this.activationInfo = new class_9225(!forClientDataPackManager, class_3289.field_14280, false);
      this.forClientDataPackManager = forClientDataPackManager;
   }

   public void method_14453(Consumer<class_3288> consumer) {
      class_9224 metadata = new class_9224("fabric", class_2561.method_43471("pack.name.fabricMods"), RESOURCE_PACK_SOURCE, Optional.empty());
      consumer.accept(class_3288.method_45275(metadata, new PlaceholderResourcePack.Factory(this.type, metadata), this.type, this.activationInfo));
      this.registerModPack(consumer, (String)null, BASE_PARENT);
      if (this.type == class_3264.field_14188) {
         this.registerModPack(consumer, "programmer_art", PROGRAMMER_ART_PARENT);
         this.registerModPack(consumer, "high_contrast", HIGH_CONTRAST_PARENT);
      }

      ResourceManagerHelperImpl.registerBuiltinResourcePacks(this.type, consumer);
   }

   private void registerModPack(Consumer<class_3288> consumer, @Nullable String subPath, Predicate<Set<String>> parents) {
      for(ModResourcePack pack : ModResourcePackUtil.getModResourcePacks(FabricLoader.getInstance(), this.type, subPath)) {
         class_3288 profile = class_3288.method_45275(pack.method_56926(), new ModResourcePackFactory(pack), this.type, this.activationInfo);
         if (profile != null) {
            if (!this.forClientDataPackManager) {
               ((FabricResourcePackProfile)profile).fabric_setParentsPredicate(parents);
            }

            consumer.accept(profile);
         }
      }

   }

   static {
      CLIENT_RESOURCE_PACK_PROVIDER = new ModResourcePackCreator(class_3264.field_14188);
      MAX_KNOWN_PACKS = Integer.getInteger("fabric-resource-loader-v0:maxKnownPacks", 1024);
   }
}
