// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.prefab.selection.buffer;

import java.nio.file.FileVisitor;
import java.util.regex.Matcher;
import java.nio.file.FileVisitResult;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.SimpleFileVisitor;
import com.hypixel.hytale.server.core.util.io.FileUtil;
import java.nio.file.NotDirectoryException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
import java.nio.file.Path;

public class PrefabLoader
{
    private static final char JSON_FILEPATH_SEPARATOR = '.';
    private final Path rootFolder;
    
    public PrefabLoader(final Path rootFolder) {
        this.rootFolder = rootFolder;
    }
    
    public Path getRootFolder() {
        return this.rootFolder;
    }
    
    public void resolvePrefabs(@Nonnull final String prefabName, @Nonnull final Consumer<Path> pathConsumer) throws IOException {
        resolvePrefabs(this.rootFolder, prefabName, pathConsumer);
    }
    
    public static void resolvePrefabs(@Nonnull final Path rootFolder, @Nonnull final String prefabName, @Nonnull final Consumer<Path> pathConsumer) throws IOException {
        if (prefabName.endsWith(".*")) {
            resolvePrefabFolder(rootFolder, prefabName, pathConsumer);
        }
        else {
            final Path prefabPath = rootFolder.resolve(prefabName.replace('.', File.separatorChar) + ".prefab.json");
            if (!Files.exists(prefabPath, new LinkOption[0])) {
                throw new NoSuchFileException(prefabPath.toString());
            }
            pathConsumer.accept(prefabPath);
        }
    }
    
    public static void resolvePrefabFolder(@Nonnull final Path rootFolder, @Nonnull final String prefabName, @Nonnull final Consumer<Path> pathConsumer) throws IOException {
        final String prefabDirectory = prefabName.substring(0, prefabName.length() - 2);
        final Path directoryPath = rootFolder.resolve(prefabDirectory.replace('.', File.separatorChar));
        if (!Files.isDirectory(directoryPath, new LinkOption[0])) {
            throw new NotDirectoryException(directoryPath.toString());
        }
        Files.walkFileTree(directoryPath, FileUtil.DEFAULT_WALK_TREE_OPTIONS_SET, Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
            @Nonnull
            @Override
            public FileVisitResult visitFile(@Nonnull final Path file, final BasicFileAttributes attrs) {
                final String fileName = file.getFileName().toString();
                final Matcher matcher = PrefabBufferUtil.FILE_SUFFIX_PATTERN.matcher(fileName);
                if (matcher.find()) {
                    final String fileNameNoExtension = matcher.replaceAll("");
                    pathConsumer.accept(file.resolveSibling(fileNameNoExtension));
                }
                return FileVisitResult.CONTINUE;
            }
        });
    }
    
    @Nonnull
    public static String resolveRelativeJsonPath(@Nonnull final String prefabName, @Nonnull final Path prefabPath, @Nonnull final Path rootPrefabDir) {
        if (!prefabName.endsWith(".*")) {
            return prefabName;
        }
        final String filepath = rootPrefabDir.relativize(prefabPath).toString();
        final int start = prefabName.equals(".*") ? 0 : (prefabName.length() - 1);
        final int length = getFilepathLengthNoExtension(filepath);
        if (length < start) {
            throw new IllegalArgumentException(String.format("Prefab key '%s' is longer than its filepath '%s'", prefabName, filepath));
        }
        final char[] chars = new char[length - start];
        filepath.getChars(start, length, chars, 0);
        for (int i = 0; i < chars.length; ++i) {
            if (chars[i] == File.separatorChar) {
                chars[i] = '.';
            }
        }
        return new String(chars);
    }
    
    private static int getFilepathLengthNoExtension(@Nonnull final String filepath) {
        int extensionSize = 0;
        if (filepath.endsWith(".prefab.json")) {
            extensionSize = ".prefab.json".length();
        }
        else if (filepath.endsWith(".prefab.json.lpf")) {
            extensionSize = ".prefab.json.lpf".length();
        }
        return filepath.length() - extensionSize;
    }
}
