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

package com.hypixel.hytale.builtin.hytalegenerator.datastructures.voxelspace;

import java.util.concurrent.ExecutionException;
import com.hypixel.hytale.common.util.ExceptionUtil;
import com.hypixel.hytale.builtin.hytalegenerator.LoggerUtil;
import java.util.concurrent.CompletableFuture;
import java.util.LinkedList;
import javax.annotation.Nonnull;

public class VoxelSpaceUtil
{
    public static <V> void parallelCopy(@Nonnull final VoxelSpace<V> source, @Nonnull final VoxelSpace<V> destination, final int concurrency) {
        if (concurrency < 1) {
            throw new IllegalArgumentException("negative concurrency");
        }
        final int minX = source.minX();
        final int minY = source.minY();
        final int minZ = source.minZ();
        final int sizeX = source.sizeX();
        final int sizeY = source.sizeY();
        final int sizeZ = source.sizeZ();
        final LinkedList<CompletableFuture<Void>> tasks = new LinkedList<CompletableFuture<Void>>();
        final int bSize = source.sizeX() * source.sizeY() * source.sizeZ() / concurrency;
        final Exception e;
        for (int b = 0; b < concurrency; ++b) {
            final int finalB = b;
            tasks.add(CompletableFuture.runAsync(() -> {
                for (int i = finalB * bSize; i < (finalB + 1) * bSize; ++i) {
                    final int x = i % sizeX + minX;
                    final int y = i / sizeX % sizeY + minY;
                    final int z = i / (sizeX * sizeY) % sizeZ + minZ;
                    if (source.isInsideSpace(x, y, z)) {
                        if (!(!destination.isInsideSpace(x, y, z))) {
                            destination.set(source.getContent(x, y, z), x, y, z);
                        }
                    }
                }
                return;
            }).handle((r, e) -> {
                if (e == null) {
                    return r;
                }
                else {
                    LoggerUtil.logException("a VoxelSpace async process", e, LoggerUtil.getLogger());
                    return null;
                }
            }));
        }
        try {
            while (!tasks.isEmpty()) {
                tasks.removeFirst().get();
            }
        }
        catch (final InterruptedException | ExecutionException e) {
            Thread.currentThread().interrupt();
            String msg = "Exception thrown by HytaleGenerator while attempting an asynchronous copy of a VoxelSpace:\n";
            msg += ExceptionUtil.toStringWithStack(e);
            LoggerUtil.getLogger().severe(msg);
        }
    }
    
    private static class BatchTransfer<T> implements Runnable
    {
        private final VoxelSpace<T> source;
        private final VoxelSpace<T> destination;
        private final int minX;
        private final int minY;
        private final int minZ;
        private final int maxX;
        private final int maxY;
        private final int maxZ;
        
        private BatchTransfer(final VoxelSpace<T> source, final VoxelSpace<T> destination, final int minX, final int minY, final int minZ, final int maxX, final int maxY, final int maxZ) {
            this.source = source;
            this.destination = destination;
            this.minX = minX;
            this.minY = minY;
            this.minZ = minZ;
            this.maxX = maxX;
            this.maxY = maxY;
            this.maxZ = maxZ;
        }
        
        @Override
        public void run() {
            try {
                for (int x = this.minX; x < this.maxX; ++x) {
                    for (int y = this.minY; y < this.maxY; ++y) {
                        for (int z = this.minZ; z < this.maxZ; ++z) {
                            if (this.destination.isInsideSpace(x, y, z)) {
                                this.destination.set(this.source.getContent(x, y, z), x, y, z);
                            }
                        }
                    }
                }
            }
            catch (final Exception e) {
                String msg = "Exception thrown by HytaleGenerator while attempting a BatchTransfer operation:\n";
                msg += ExceptionUtil.toStringWithStack(e);
                LoggerUtil.getLogger().severe(msg);
            }
        }
    }
}
