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

package com.hypixel.hytale.builtin.path;

import it.unimi.dsi.fastutil.ints.Int2ObjectFunction;
import java.util.Collections;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List;
import com.hypixel.fastutil.ints.Int2ObjectConcurrentHashMap;
import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.path.path.IPrefabPath;
import com.hypixel.hytale.component.ComponentAccessor;
import java.util.UUID;
import java.util.Set;
import javax.annotation.Nonnull;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.component.ResourceType;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Resource;

public class WorldPathData implements Resource<EntityStore>
{
    private final Int2ObjectMap<PrefabPathCollection> prefabPaths;
    
    public WorldPathData() {
        this.prefabPaths = new Int2ObjectOpenHashMap<PrefabPathCollection>();
    }
    
    public static ResourceType<EntityStore, WorldPathData> getResourceType() {
        return PathPlugin.get().getWorldPathDataResourceType();
    }
    
    @Nullable
    public IPrefabPath getNearestPrefabPath(final int worldgenId, final int nameIndex, @Nonnull final Vector3d position, final Set<UUID> disallowedPaths, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final PrefabPathCollection entry = this.getPrefabPathCollection(worldgenId);
        return entry.getNearestPrefabPath(nameIndex, position, disallowedPaths, componentAccessor);
    }
    
    @Nullable
    public IPrefabPath getNearestPrefabPath(final int worldgenId, @Nonnull final Vector3d position, final Set<UUID> disallowedPaths, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        return this.getPrefabPathCollection(worldgenId).getNearestPrefabPath(position, disallowedPaths, componentAccessor);
    }
    
    public IPrefabPath getOrConstructPrefabPath(final int worldgenId, @Nonnull final UUID id, @Nonnull final String name, @Nonnull final Int2ObjectConcurrentHashMap.IntBiObjFunction<UUID, String, IPrefabPath> pathGenerator) {
        final PrefabPathCollection entry = this.getPrefabPathCollection(worldgenId);
        return entry.getOrConstructPath(id, name, pathGenerator);
    }
    
    public void removePrefabPathWaypoint(final int worldgenId, final UUID id, final int index) {
        final PrefabPathCollection entry = this.getPrefabPathCollection(worldgenId);
        entry.removePathWaypoint(id, index);
        if (entry.isEmpty()) {
            this.prefabPaths.remove(worldgenId);
        }
    }
    
    public void unloadPrefabPathWaypoint(final int worldgenId, final UUID id, final int index) {
        final PrefabPathCollection entry = this.getPrefabPathCollection(worldgenId);
        entry.unloadPathWaypoint(id, index);
        if (entry.isEmpty()) {
            this.prefabPaths.remove(worldgenId);
        }
    }
    
    public void removePrefabPath(final int worldgenId, final UUID id) {
        final PrefabPathCollection entry = this.getPrefabPathCollection(worldgenId);
        entry.removePath(id);
        if (entry.isEmpty()) {
            this.prefabPaths.remove(worldgenId);
        }
    }
    
    @Nullable
    public IPrefabPath getPrefabPath(final int worldgenId, final UUID id, final boolean ignoreLoadState) {
        final PrefabPathCollection collection = this.getPrefabPathCollection(worldgenId);
        final IPrefabPath path = collection.getPath(id);
        if (!ignoreLoadState && (path == null || !path.isFullyLoaded())) {
            return null;
        }
        return path;
    }
    
    public void compactPrefabPath(final int worldgenId, final UUID id) {
        final IPrefabPath path = this.getPrefabPath(worldgenId, id, true);
        if (path == null) {
            return;
        }
        path.compact(worldgenId);
    }
    
    @Nonnull
    public List<IPrefabPath> getAllPrefabPaths() {
        final ObjectArrayList<IPrefabPath> list = new ObjectArrayList<IPrefabPath>();
        this.prefabPaths.forEach((id, entry) -> entry.forEach((key, path) -> list.add(path)));
        return Collections.unmodifiableList((List<? extends IPrefabPath>)list);
    }
    
    @Nonnull
    public PrefabPathCollection getPrefabPathCollection(final int worldgenId) {
        return this.prefabPaths.computeIfAbsent(worldgenId, PrefabPathCollection::new);
    }
    
    @Override
    public Resource<EntityStore> clone() {
        throw new UnsupportedOperationException("Not implemented!");
    }
}
