package net.minecraft.nbt;

import java.util.AbstractList;
import org.apache.logging.log4j.LogManager;
import com.mojang.datafixers.types.DynamicOps;
import com.mojang.datafixers.Dynamic;
import net.minecraft.SharedConstants;
import net.minecraft.util.datafix.DataFixTypes;
import com.mojang.datafixers.DataFixer;
import com.google.common.collect.UnmodifiableIterator;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.Optional;
import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.Registry;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import com.google.common.annotations.VisibleForTesting;
import net.minecraft.util.StringUtil;
import javax.annotation.Nullable;
import java.util.Iterator;
import com.mojang.authlib.properties.Property;
import java.util.UUID;
import com.mojang.authlib.GameProfile;
import org.apache.logging.log4j.Logger;

public final class NbtUtils {
    private static final Logger LOGGER;
    
    @Nullable
    public static GameProfile readGameProfile(final CompoundTag jt) {
        String string2 = null;
        String string3 = null;
        if (jt.contains("Name", 8)) {
            string2 = jt.getString("Name");
        }
        Label_0040: {
            if (!jt.contains("Id", 8)) {
                break Label_0040;
            }
            string3 = jt.getString("Id");
            try {
                UUID uUID4;
                try {
                    uUID4 = UUID.fromString(string3);
                }
                catch (Throwable throwable5) {
                    uUID4 = null;
                }
                final GameProfile gameProfile5 = new GameProfile(uUID4, string2);
                if (jt.contains("Properties", 10)) {
                    final CompoundTag jt2 = jt.getCompound("Properties");
                    for (final String string4 : jt2.getAllKeys()) {
                        final ListTag jz9 = jt2.getList(string4, 10);
                        for (int integer10 = 0; integer10 < jz9.size(); ++integer10) {
                            final CompoundTag jt3 = jz9.getCompound(integer10);
                            final String string5 = jt3.getString("Value");
                            if (jt3.contains("Signature", 8)) {
                                gameProfile5.getProperties().put(string4, new Property(string4, string5, jt3.getString("Signature")));
                            }
                            else {
                                gameProfile5.getProperties().put(string4, new Property(string4, string5));
                            }
                        }
                    }
                }
                return gameProfile5;
            }
            catch (Throwable t) {
                return null;
            }
        }
    }
    
    public static CompoundTag writeGameProfile(final CompoundTag jt, final GameProfile gameProfile) {
        if (!StringUtil.isNullOrEmpty(gameProfile.getName())) {
            jt.putString("Name", gameProfile.getName());
        }
        if (gameProfile.getId() != null) {
            jt.putString("Id", gameProfile.getId().toString());
        }
        if (!gameProfile.getProperties().isEmpty()) {
            final CompoundTag jt2 = new CompoundTag();
            for (final String string5 : gameProfile.getProperties().keySet()) {
                final ListTag jz6 = new ListTag();
                for (final Property property8 : gameProfile.getProperties().get(string5)) {
                    final CompoundTag jt3 = new CompoundTag();
                    jt3.putString("Value", property8.getValue());
                    if (property8.hasSignature()) {
                        jt3.putString("Signature", property8.getSignature());
                    }
                    ((AbstractList<CompoundTag>)jz6).add(jt3);
                }
                jt2.put(string5, jz6);
            }
            jt.put("Properties", jt2);
        }
        return jt;
    }
    
    @VisibleForTesting
    public static boolean compareNbt(@Nullable final Tag kj1, @Nullable final Tag kj2, final boolean boolean3) {
        if (kj1 == kj2) {
            return true;
        }
        if (kj1 == null) {
            return true;
        }
        if (kj2 == null) {
            return false;
        }
        if (!kj1.getClass().equals(kj2.getClass())) {
            return false;
        }
        if (kj1 instanceof CompoundTag) {
            final CompoundTag jt4 = (CompoundTag)kj1;
            final CompoundTag jt5 = (CompoundTag)kj2;
            for (final String string7 : jt4.getAllKeys()) {
                final Tag kj3 = jt4.get(string7);
                if (!compareNbt(kj3, jt5.get(string7), boolean3)) {
                    return false;
                }
            }
            return true;
        }
        if (!(kj1 instanceof ListTag) || !boolean3) {
            return kj1.equals(kj2);
        }
        final ListTag jz4 = (ListTag)kj1;
        final ListTag jz5 = (ListTag)kj2;
        if (jz4.isEmpty()) {
            return jz5.isEmpty();
        }
        for (int integer6 = 0; integer6 < jz4.size(); ++integer6) {
            final Tag kj4 = jz4.get(integer6);
            boolean boolean4 = false;
            for (int integer7 = 0; integer7 < jz5.size(); ++integer7) {
                if (compareNbt(kj4, jz5.get(integer7), boolean3)) {
                    boolean4 = true;
                    break;
                }
            }
            if (!boolean4) {
                return false;
            }
        }
        return true;
    }
    
    public static CompoundTag createUUIDTag(final UUID uUID) {
        final CompoundTag jt2 = new CompoundTag();
        jt2.putLong("M", uUID.getMostSignificantBits());
        jt2.putLong("L", uUID.getLeastSignificantBits());
        return jt2;
    }
    
    public static UUID loadUUIDTag(final CompoundTag jt) {
        return new UUID(jt.getLong("M"), jt.getLong("L"));
    }
    
    public static BlockPos readBlockPos(final CompoundTag jt) {
        return new BlockPos(jt.getInt("X"), jt.getInt("Y"), jt.getInt("Z"));
    }
    
    public static CompoundTag writeBlockPos(final BlockPos fk) {
        final CompoundTag jt2 = new CompoundTag();
        jt2.putInt("X", fk.getX());
        jt2.putInt("Y", fk.getY());
        jt2.putInt("Z", fk.getZ());
        return jt2;
    }
    
    public static BlockState readBlockState(final CompoundTag jt) {
        if (!jt.contains("Name", 8)) {
            return Blocks.AIR.defaultBlockState();
        }
        final Block bph2 = Registry.BLOCK.get(new ResourceLocation(jt.getString("Name")));
        BlockState byj3 = bph2.defaultBlockState();
        if (jt.contains("Properties", 10)) {
            final CompoundTag jt2 = jt.getCompound("Properties");
            final StateDefinition<Block, BlockState> byk5 = bph2.getStateDefinition();
            for (final String string7 : jt2.getAllKeys()) {
                final net.minecraft.world.level.block.state.properties.Property<?> bzm8 = byk5.getProperty(string7);
                if (bzm8 != null) {
                    byj3 = NbtUtils.setValueHelper(byj3, bzm8, string7, jt2, jt);
                }
            }
        }
        return byj3;
    }
    
    private static <S extends StateHolder<S>, T extends Comparable<T>> S setValueHelper(final S byl, final net.minecraft.world.level.block.state.properties.Property<T> bzm, final String string, final CompoundTag jt4, final CompoundTag jt5) {
        final Optional<T> optional6 = bzm.getValue(jt4.getString(string));
        if (optional6.isPresent()) {
            return byl.<T, T>setValue(bzm, optional6.get());
        }
        NbtUtils.LOGGER.warn("Unable to read property: {} with value: {} for blockstate: {}", string, jt4.getString(string), jt5.toString());
        return byl;
    }
    
    public static CompoundTag writeBlockState(final BlockState byj) {
        final CompoundTag jt2 = new CompoundTag();
        jt2.putString("Name", Registry.BLOCK.getKey(byj.getBlock()).toString());
        final ImmutableMap<net.minecraft.world.level.block.state.properties.Property<?>, Comparable<?>> immutableMap3 = byj.getValues();
        if (!immutableMap3.isEmpty()) {
            final CompoundTag jt3 = new CompoundTag();
            for (final Map.Entry<net.minecraft.world.level.block.state.properties.Property<?>, Comparable<?>> entry6 : immutableMap3.entrySet()) {
                final net.minecraft.world.level.block.state.properties.Property<?> bzm7 = entry6.getKey();
                jt3.putString(bzm7.getName(), NbtUtils.getName(bzm7, entry6.getValue()));
            }
            jt2.put("Properties", jt3);
        }
        return jt2;
    }
    
    private static <T extends Comparable<T>> String getName(final net.minecraft.world.level.block.state.properties.Property<T> bzm, final Comparable<?> comparable) {
        return bzm.getName((T)comparable);
    }
    
    public static CompoundTag update(final DataFixer dataFixer, final DataFixTypes acd, final CompoundTag jt, final int integer) {
        return update(dataFixer, acd, jt, integer, SharedConstants.getCurrentVersion().getWorldVersion());
    }
    
    public static CompoundTag update(final DataFixer dataFixer, final DataFixTypes acd, final CompoundTag jt, final int integer4, final int integer5) {
        return (CompoundTag)dataFixer.update(acd.getType(), new Dynamic((DynamicOps)NbtOps.INSTANCE, jt), integer4, integer5).getValue();
    }
    
    static {
        LOGGER = LogManager.getLogger();
    }
}
