package net.minecraft.server.packs;

import net.minecraft.Util;
import com.google.common.collect.Maps;
import org.apache.logging.log4j.LogManager;
import java.nio.file.FileSystemNotFoundException;
import java.util.Collections;
import java.nio.file.FileSystems;
import java.util.HashMap;
import net.minecraft.server.packs.metadata.MetadataSectionSerializer;
import java.io.File;
import javax.annotation.Nullable;
import java.util.stream.Stream;
import java.util.function.Consumer;
import java.nio.file.FileVisitOption;
import java.net.URI;
import java.util.Enumeration;
import java.nio.file.NoSuchFileException;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.net.URL;
import com.google.common.collect.Sets;
import java.util.Collection;
import java.util.function.Predicate;
import java.io.FileNotFoundException;
import net.minecraft.resources.ResourceLocation;
import java.io.IOException;
import java.nio.file.OpenOption;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.io.InputStream;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import java.nio.file.FileSystem;
import java.util.Map;
import org.apache.logging.log4j.Logger;
import java.nio.file.Path;

public class VanillaPackResources implements PackResources {
    public static Path generatedDir;
    private static final Logger LOGGER;
    public static Class<?> clientObject;
    private static final Map<PackType, FileSystem> JAR_FILESYSTEM_BY_TYPE;
    public final Set<String> namespaces;
    
    public VanillaPackResources(final String... arr) {
        this.namespaces = ImmutableSet.<String>copyOf(arr);
    }
    
    @Override
    public InputStream getRootResource(final String string) throws IOException {
        if (string.contains("/") || string.contains("\\")) {
            throw new IllegalArgumentException("Root resources can only be filenames, not paths (no / allowed!)");
        }
        if (VanillaPackResources.generatedDir != null) {
            final Path path3 = VanillaPackResources.generatedDir.resolve(string);
            if (Files.exists(path3)) {
                return Files.newInputStream(path3);
            }
        }
        return this.getResourceAsStream(string);
    }
    
    @Override
    public InputStream getResource(final PackType aaf, final ResourceLocation uh) throws IOException {
        final InputStream inputStream4 = this.getResourceAsStream(aaf, uh);
        if (inputStream4 != null) {
            return inputStream4;
        }
        throw new FileNotFoundException(uh.getPath());
    }
    
    @Override
    public Collection<ResourceLocation> getResources(final PackType aaf, final String string2, final String string3, final int integer, final Predicate<String> predicate) {
        final Set<ResourceLocation> set7 = Sets.newHashSet();
        if (VanillaPackResources.generatedDir != null) {
            try {
                getResources(set7, integer, string2, VanillaPackResources.generatedDir.resolve(aaf.getDirectory()), string3, predicate);
            }
            catch (IOException ex2) {}
            if (aaf == PackType.CLIENT_RESOURCES) {
                Enumeration<URL> enumeration8 = null;
                try {
                    enumeration8 = VanillaPackResources.clientObject.getClassLoader().getResources(aaf.getDirectory() + "/");
                }
                catch (IOException ex3) {}
                while (enumeration8 != null && enumeration8.hasMoreElements()) {
                    try {
                        final URI uRI9 = enumeration8.nextElement().toURI();
                        if (!"file".equals(uRI9.getScheme())) {
                            continue;
                        }
                        getResources(set7, integer, string2, Paths.get(uRI9), string3, predicate);
                    }
                    catch (URISyntaxException | IOException ex4) {}
                }
            }
        }
        try {
            final URL uRL8 = VanillaPackResources.class.getResource("/" + aaf.getDirectory() + "/.mcassetsroot");
            if (uRL8 == null) {
                VanillaPackResources.LOGGER.error("Couldn't find .mcassetsroot, cannot load vanilla resources");
                return set7;
            }
            final URI uRI9 = uRL8.toURI();
            if ("file".equals(uRI9.getScheme())) {
                final URL uRL9 = new URL(uRL8.toString().substring(0, uRL8.toString().length() - ".mcassetsroot".length()));
                final Path path11 = Paths.get(uRL9.toURI());
                getResources(set7, integer, string2, path11, string3, predicate);
            }
            else if ("jar".equals(uRI9.getScheme())) {
                final Path path12 = VanillaPackResources.JAR_FILESYSTEM_BY_TYPE.get(aaf).getPath("/" + aaf.getDirectory());
                getResources(set7, integer, "minecraft", path12, string3, predicate);
            }
            else {
                VanillaPackResources.LOGGER.error("Unsupported scheme {} trying to list vanilla resources (NYI?)", uRI9);
            }
        }
        catch (FileNotFoundException | NoSuchFileException ex5) {}
        catch (URISyntaxException | IOException ex6) {
            final Exception ex;
            final Exception exception8 = ex;
            VanillaPackResources.LOGGER.error("Couldn't get a list of all vanilla resources", (Throwable)exception8);
        }
        return set7;
    }
    
    private static void getResources(final Collection<ResourceLocation> collection, final int integer, final String string3, final Path path, final String string5, final Predicate<String> predicate) throws IOException {
        final Path path4 = path.resolve(string3);
        try (final Stream<Path> stream8 = Files.walk(path4.resolve(string5), integer)) {
            stream8.filter(path -> !path.endsWith(".mcmeta") && Files.isRegularFile(path) && predicate.test(path.getFileName().toString())).map(path3 -> new ResourceLocation(string3, path4.relativize(path3).toString().replaceAll("\\\\", "/"))).forEach(collection::add);
        }
    }
    
    @Nullable
    protected InputStream getResourceAsStream(final PackType aaf, final ResourceLocation uh) {
        final String string4 = createPath(aaf, uh);
        if (VanillaPackResources.generatedDir != null) {
            final Path path5 = VanillaPackResources.generatedDir.resolve(aaf.getDirectory() + "/" + uh.getNamespace() + "/" + uh.getPath());
            if (Files.exists(path5)) {
                try {
                    return Files.newInputStream(path5);
                }
                catch (IOException ex) {}
            }
        }
        try {
            final URL uRL5 = VanillaPackResources.class.getResource(string4);
            if (isResourceUrlValid(string4, uRL5)) {
                return uRL5.openStream();
            }
        }
        catch (IOException iOException5) {
            return VanillaPackResources.class.getResourceAsStream(string4);
        }
        return null;
    }
    
    private static String createPath(final PackType aaf, final ResourceLocation uh) {
        return "/" + aaf.getDirectory() + "/" + uh.getNamespace() + "/" + uh.getPath();
    }
    
    private static boolean isResourceUrlValid(final String string, @Nullable final URL uRL) throws IOException {
        return uRL != null && (uRL.getProtocol().equals("jar") || FolderPackResources.validatePath(new File(uRL.getFile()), string));
    }
    
    @Nullable
    protected InputStream getResourceAsStream(final String string) {
        return VanillaPackResources.class.getResourceAsStream("/" + string);
    }
    
    @Override
    public boolean hasResource(final PackType aaf, final ResourceLocation uh) {
        final String string4 = createPath(aaf, uh);
        if (VanillaPackResources.generatedDir != null) {
            final Path path5 = VanillaPackResources.generatedDir.resolve(aaf.getDirectory() + "/" + uh.getNamespace() + "/" + uh.getPath());
            if (Files.exists(path5)) {
                return true;
            }
        }
        try {
            final URL uRL5 = VanillaPackResources.class.getResource(string4);
            return isResourceUrlValid(string4, uRL5);
        }
        catch (IOException ex) {
            return false;
        }
    }
    
    @Override
    public Set<String> getNamespaces(final PackType aaf) {
        return this.namespaces;
    }
    
    @Nullable
    @Override
    public <T> T getMetadataSection(final MetadataSectionSerializer<T> aai) throws IOException {
        try (final InputStream inputStream3 = this.getRootResource("pack.mcmeta")) {
            return AbstractPackResources.<T>getMetadataFromStream(aai, inputStream3);
        }
        catch (RuntimeException | FileNotFoundException ex2) {
            final Exception ex;
            final Exception exception3 = ex;
            return null;
        }
    }
    
    @Override
    public String getName() {
        return "Default";
    }
    
    @Override
    public void close() {
    }
    
    static {
        LOGGER = LogManager.getLogger();
        final PackType[] array;
        int length;
        int i = 0;
        PackType aaf6;
        URL uRL7;
        URI uRI8;
        FileSystem fileSystem9;
        final Exception ex;
        Exception exception8;
        JAR_FILESYSTEM_BY_TYPE = Util.<Map<PackType, FileSystem>>make(Maps.newHashMap(), hashMap -> {
            synchronized (VanillaPackResources.class) {
                PackType.values();
                for (length = array.length; i < length; ++i) {
                    aaf6 = array[i];
                    uRL7 = VanillaPackResources.class.getResource("/" + aaf6.getDirectory() + "/.mcassetsroot");
                    try {
                        uRI8 = uRL7.toURI();
                        if ("jar".equals(uRI8.getScheme())) {
                            try {
                                fileSystem9 = FileSystems.getFileSystem(uRI8);
                            }
                            catch (FileSystemNotFoundException fileSystemNotFoundException10) {
                                fileSystem9 = FileSystems.newFileSystem(uRI8, Collections.emptyMap());
                            }
                            hashMap.put(aaf6, fileSystem9);
                        }
                    }
                    catch (URISyntaxException | IOException ex2) {
                        exception8 = ex;
                        VanillaPackResources.LOGGER.error("Couldn't get a list of all vanilla resources", (Throwable)exception8);
                    }
                }
            }
        });
    }
}
