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

package com.hypixel.hytale.server.worldgen.loader.util;

import com.hypixel.hytale.math.util.MathUtil;
import com.google.gson.JsonObject;
import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
import com.google.gson.JsonArray;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
import com.hypixel.hytale.server.worldgen.util.BlockFluidEntry;
import com.hypixel.hytale.server.core.asset.type.fluid.Fluid;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.google.gson.JsonElement;
import java.nio.file.Path;
import javax.annotation.Nonnull;
import com.hypixel.hytale.procedurallib.json.SeedString;
import com.hypixel.hytale.server.worldgen.util.ResolvedBlockArray;
import com.hypixel.hytale.server.worldgen.SeedStringResource;
import com.hypixel.hytale.procedurallib.json.JsonLoader;

public class ResolvedBlockArrayJsonLoader extends JsonLoader<SeedStringResource, ResolvedBlockArray>
{
    public ResolvedBlockArrayJsonLoader(@Nonnull final SeedString<SeedStringResource> seed, final Path dataFolder, final JsonElement json) {
        super(seed.append("ResolvedBlockArray"), dataFolder, json);
    }
    
    @Override
    public ResolvedBlockArray load() {
        if (this.json == null || this.json.isJsonNull()) {
            return ResolvedBlockArray.EMPTY;
        }
        if (!this.json.isJsonArray()) {
            if (this.json.isJsonObject()) {
                return loadSingleBlock(this.json.getAsJsonObject());
            }
            return this.loadSingleBlock(this.json.getAsString());
        }
        else {
            final JsonArray jsonArray = this.json.getAsJsonArray();
            if (jsonArray.size() != 1) {
                final BlockTypeAssetMap<String, BlockType> assetMap = BlockType.getAssetMap();
                final IndexedLookupTableAssetMap<String, Fluid> fluidMap = Fluid.getAssetMap();
                final BlockFluidEntry[] blocks = new BlockFluidEntry[jsonArray.size()];
                for (int k = 0; k < blocks.length; ++k) {
                    final JsonElement elm = jsonArray.get(k);
                    if (elm.isJsonObject()) {
                        final JsonObject obj = elm.getAsJsonObject();
                        int blockIndex = 0;
                        int rotation = 0;
                        int fluidIndex = 0;
                        if (obj.has("Block")) {
                            final BlockPattern.BlockEntry key = BlockPattern.BlockEntry.decode(obj.get("Block").getAsString());
                            final int index = BlockType.getBlockIdOrUnknown(key.blockTypeKey(), "Failed to find block '%s' in resolved block array!", key.blockTypeKey());
                            if (index == Integer.MIN_VALUE) {
                                throw new IllegalArgumentException("Unknown key! " + String.valueOf(key));
                            }
                            blockIndex = index;
                            rotation = key.rotation();
                        }
                        if (obj.has("Fluid")) {
                            final String key2 = obj.get("Fluid").getAsString();
                            final int index = Fluid.getFluidIdOrUnknown(key2, "Failed to find fluid '%s' in resolved block array!", key2);
                            if (index == Integer.MIN_VALUE) {
                                throw new IllegalArgumentException("Unknown key! " + key2);
                            }
                            fluidIndex = index;
                        }
                        blocks[k] = new BlockFluidEntry(blockIndex, rotation, fluidIndex);
                    }
                    else {
                        final String blockName = elm.getAsString();
                        try {
                            final BlockPattern.BlockEntry key3 = BlockPattern.BlockEntry.decode(blockName);
                            final int index2 = BlockType.getBlockIdOrUnknown(key3.blockTypeKey(), "Failed to find block '%s' in resolved block array!", key3.blockTypeKey());
                            if (index2 == Integer.MIN_VALUE) {
                                throw new IllegalArgumentException("Unknown key! " + String.valueOf(key3));
                            }
                            blocks[k] = new BlockFluidEntry(index2, key3.rotation(), 0);
                        }
                        catch (final IllegalArgumentException e) {
                            throw new IllegalArgumentException("BlockLayer " + blockName + " does not exist in BlockTypes", (Throwable)e);
                        }
                    }
                }
                return new ResolvedBlockArray(blocks);
            }
            if (jsonArray.get(0).isJsonObject()) {
                return loadSingleBlock(jsonArray.get(0).getAsJsonObject());
            }
            return this.loadSingleBlock(jsonArray.get(0).getAsString());
        }
    }
    
    @Nonnull
    public ResolvedBlockArray loadSingleBlock(@Nonnull final String blockName) {
        final BlockTypeAssetMap<String, BlockType> assetMap = BlockType.getAssetMap();
        try {
            final BlockPattern.BlockEntry key = BlockPattern.BlockEntry.decode(blockName);
            final int index = assetMap.getIndex(key.blockTypeKey());
            if (index == Integer.MIN_VALUE) {
                throw new IllegalArgumentException("Unknown key! " + String.valueOf(key));
            }
            final long mapIndex = MathUtil.packLong(index, 0);
            if (key.rotation() == 0) {
                final ResolvedBlockArray cachedResolvedBlockArray = ResolvedBlockArray.RESOLVED_BLOCKS.get(mapIndex);
                if (cachedResolvedBlockArray != null) {
                    return cachedResolvedBlockArray;
                }
            }
            final ResolvedBlockArray resolvedBlockArray = new ResolvedBlockArray(new BlockFluidEntry[] { new BlockFluidEntry(index, key.rotation(), 0) });
            if (key.rotation() == 0) {
                ResolvedBlockArray.RESOLVED_BLOCKS.put(mapIndex, resolvedBlockArray);
            }
            return resolvedBlockArray;
        }
        catch (final IllegalArgumentException e) {
            throw new IllegalArgumentException("BlockLayer does not exist in BlockTypes", e);
        }
    }
    
    @Nonnull
    public static ResolvedBlockArray loadSingleBlock(@Nonnull final JsonObject obj) {
        final BlockTypeAssetMap<String, BlockType> assetMap = BlockType.getAssetMap();
        final IndexedLookupTableAssetMap<String, Fluid> fluidMap = Fluid.getAssetMap();
        try {
            int blockIndex = 0;
            int rotation = 0;
            int fluidIndex = 0;
            if (obj.has("Block")) {
                final BlockPattern.BlockEntry key = BlockPattern.BlockEntry.decode(obj.get("Block").getAsString());
                final int index = assetMap.getIndex(key.blockTypeKey());
                if (index == Integer.MIN_VALUE) {
                    throw new IllegalArgumentException("Unknown key! " + String.valueOf(key));
                }
                blockIndex = index;
                rotation = key.rotation();
            }
            if (obj.has("Fluid")) {
                final String key2 = obj.get("Fluid").getAsString();
                final int index = fluidMap.getIndex(key2);
                if (index == Integer.MIN_VALUE) {
                    throw new IllegalArgumentException("Unknown key! " + key2);
                }
                fluidIndex = index;
            }
            final long mapIndex = MathUtil.packLong(blockIndex, fluidIndex);
            if (rotation == 0) {
                final ResolvedBlockArray cachedResolvedBlockArray = ResolvedBlockArray.RESOLVED_BLOCKS.get(mapIndex);
                if (cachedResolvedBlockArray != null) {
                    return cachedResolvedBlockArray;
                }
            }
            final ResolvedBlockArray resolvedBlockArray = new ResolvedBlockArray(new BlockFluidEntry[] { new BlockFluidEntry(blockIndex, rotation, fluidIndex) });
            if (rotation == 0) {
                ResolvedBlockArray.RESOLVED_BLOCKS.put(mapIndex, resolvedBlockArray);
            }
            return resolvedBlockArray;
        }
        catch (final IllegalArgumentException e) {
            throw new IllegalArgumentException("BlockLayer does not exist in BlockTypes", e);
        }
    }
}
