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

package com.hypixel.hytale.builtin.portals.utils.posqueries;

import java.util.logging.Level;
import com.hypixel.hytale.logger.HytaleLogger;
import java.util.function.Function;
import java.util.Objects;
import java.util.Optional;
import com.hypixel.hytale.builtin.portals.utils.posqueries.predicates.generic.FilterQuery;
import com.hypixel.hytale.builtin.portals.utils.posqueries.predicates.generic.FlatMapQuery;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.server.core.universe.world.World;

public interface SpatialQuery
{
    Stream<Vector3d> createCandidates(final World p0, final Vector3d p1, @Nullable final SpatialQueryDebug p2);
    
    default SpatialQuery then(final SpatialQuery expand) {
        return new FlatMapQuery(this, expand);
    }
    
    default SpatialQuery filter(final PositionPredicate predicate) {
        return new FilterQuery(this, predicate);
    }
    
    default Optional<Vector3d> execute(final World world, final Vector3d origin) {
        return this.createCandidates(world, origin, null).findFirst();
    }
    
    default Optional<Vector3d> debug(final World world, final Vector3d origin) {
        try {
            final SpatialQueryDebug debug = new SpatialQueryDebug();
            final Optional<Vector3d> output = this.createCandidates(world, origin, debug).findFirst();
            final SpatialQueryDebug spatialQueryDebug = debug;
            final Optional<Vector3d> optional = output;
            final SpatialQueryDebug obj = debug;
            Objects.requireNonNull(obj);
            spatialQueryDebug.appendLine("-> OUTPUT: " + (String)optional.map((Function<? super Vector3d, ?>)obj::fmt).orElse("<null>"));
            HytaleLogger.getLogger().at(Level.INFO).log(debug.toString());
            return output;
        }
        catch (final Throwable t) {
            HytaleLogger.getLogger().at(Level.SEVERE).withCause(t).log("Error in SpatialQuery");
            throw new RuntimeException("Error in SpatialQuery", t);
        }
    }
}
