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

package com.hypixel.hytale.protocol.packets.buildertools;

import java.util.Objects;
import com.hypixel.hytale.protocol.io.ValidationResult;
import com.hypixel.hytale.protocol.io.PacketIO;
import io.netty.buffer.ByteBuf;
import javax.annotation.Nullable;
import javax.annotation.Nonnull;

public class BuilderToolArg
{
    public static final int NULLABLE_BIT_FIELD_SIZE = 2;
    public static final int FIXED_BLOCK_SIZE = 33;
    public static final int VARIABLE_FIELD_COUNT = 4;
    public static final int VARIABLE_BLOCK_START = 49;
    public static final int MAX_SIZE = 1677721600;
    public boolean required;
    @Nonnull
    public BuilderToolArgType argType;
    @Nullable
    public BuilderToolBoolArg boolArg;
    @Nullable
    public BuilderToolFloatArg floatArg;
    @Nullable
    public BuilderToolIntArg intArg;
    @Nullable
    public BuilderToolStringArg stringArg;
    @Nullable
    public BuilderToolBlockArg blockArg;
    @Nullable
    public BuilderToolMaskArg maskArg;
    @Nullable
    public BuilderToolBrushShapeArg brushShapeArg;
    @Nullable
    public BuilderToolBrushOriginArg brushOriginArg;
    @Nullable
    public BuilderToolBrushAxisArg brushAxisArg;
    @Nullable
    public BuilderToolRotationArg rotationArg;
    @Nullable
    public BuilderToolOptionArg optionArg;
    
    public BuilderToolArg() {
        this.argType = BuilderToolArgType.Bool;
    }
    
    public BuilderToolArg(final boolean required, @Nonnull final BuilderToolArgType argType, @Nullable final BuilderToolBoolArg boolArg, @Nullable final BuilderToolFloatArg floatArg, @Nullable final BuilderToolIntArg intArg, @Nullable final BuilderToolStringArg stringArg, @Nullable final BuilderToolBlockArg blockArg, @Nullable final BuilderToolMaskArg maskArg, @Nullable final BuilderToolBrushShapeArg brushShapeArg, @Nullable final BuilderToolBrushOriginArg brushOriginArg, @Nullable final BuilderToolBrushAxisArg brushAxisArg, @Nullable final BuilderToolRotationArg rotationArg, @Nullable final BuilderToolOptionArg optionArg) {
        this.argType = BuilderToolArgType.Bool;
        this.required = required;
        this.argType = argType;
        this.boolArg = boolArg;
        this.floatArg = floatArg;
        this.intArg = intArg;
        this.stringArg = stringArg;
        this.blockArg = blockArg;
        this.maskArg = maskArg;
        this.brushShapeArg = brushShapeArg;
        this.brushOriginArg = brushOriginArg;
        this.brushAxisArg = brushAxisArg;
        this.rotationArg = rotationArg;
        this.optionArg = optionArg;
    }
    
    public BuilderToolArg(@Nonnull final BuilderToolArg other) {
        this.argType = BuilderToolArgType.Bool;
        this.required = other.required;
        this.argType = other.argType;
        this.boolArg = other.boolArg;
        this.floatArg = other.floatArg;
        this.intArg = other.intArg;
        this.stringArg = other.stringArg;
        this.blockArg = other.blockArg;
        this.maskArg = other.maskArg;
        this.brushShapeArg = other.brushShapeArg;
        this.brushOriginArg = other.brushOriginArg;
        this.brushAxisArg = other.brushAxisArg;
        this.rotationArg = other.rotationArg;
        this.optionArg = other.optionArg;
    }
    
    @Nonnull
    public static BuilderToolArg deserialize(@Nonnull final ByteBuf buf, final int offset) {
        final BuilderToolArg obj = new BuilderToolArg();
        final byte[] nullBits = PacketIO.readBytes(buf, offset, 2);
        obj.required = (buf.getByte(offset + 2) != 0);
        obj.argType = BuilderToolArgType.fromValue(buf.getByte(offset + 3));
        if ((nullBits[0] & 0x1) != 0x0) {
            obj.boolArg = BuilderToolBoolArg.deserialize(buf, offset + 4);
        }
        if ((nullBits[0] & 0x2) != 0x0) {
            obj.floatArg = BuilderToolFloatArg.deserialize(buf, offset + 5);
        }
        if ((nullBits[0] & 0x4) != 0x0) {
            obj.intArg = BuilderToolIntArg.deserialize(buf, offset + 17);
        }
        if ((nullBits[0] & 0x8) != 0x0) {
            obj.brushShapeArg = BuilderToolBrushShapeArg.deserialize(buf, offset + 29);
        }
        if ((nullBits[0] & 0x10) != 0x0) {
            obj.brushOriginArg = BuilderToolBrushOriginArg.deserialize(buf, offset + 30);
        }
        if ((nullBits[0] & 0x20) != 0x0) {
            obj.brushAxisArg = BuilderToolBrushAxisArg.deserialize(buf, offset + 31);
        }
        if ((nullBits[0] & 0x40) != 0x0) {
            obj.rotationArg = BuilderToolRotationArg.deserialize(buf, offset + 32);
        }
        if ((nullBits[0] & 0x80) != 0x0) {
            final int varPos0 = offset + 49 + buf.getIntLE(offset + 33);
            obj.stringArg = BuilderToolStringArg.deserialize(buf, varPos0);
        }
        if ((nullBits[1] & 0x1) != 0x0) {
            final int varPos2 = offset + 49 + buf.getIntLE(offset + 37);
            obj.blockArg = BuilderToolBlockArg.deserialize(buf, varPos2);
        }
        if ((nullBits[1] & 0x2) != 0x0) {
            final int varPos3 = offset + 49 + buf.getIntLE(offset + 41);
            obj.maskArg = BuilderToolMaskArg.deserialize(buf, varPos3);
        }
        if ((nullBits[1] & 0x4) != 0x0) {
            final int varPos4 = offset + 49 + buf.getIntLE(offset + 45);
            obj.optionArg = BuilderToolOptionArg.deserialize(buf, varPos4);
        }
        return obj;
    }
    
    public static int computeBytesConsumed(@Nonnull final ByteBuf buf, final int offset) {
        final byte[] nullBits = PacketIO.readBytes(buf, offset, 2);
        int maxEnd = 49;
        if ((nullBits[0] & 0x80) != 0x0) {
            final int fieldOffset0 = buf.getIntLE(offset + 33);
            int pos0 = offset + 49 + fieldOffset0;
            pos0 += BuilderToolStringArg.computeBytesConsumed(buf, pos0);
            if (pos0 - offset > maxEnd) {
                maxEnd = pos0 - offset;
            }
        }
        if ((nullBits[1] & 0x1) != 0x0) {
            final int fieldOffset2 = buf.getIntLE(offset + 37);
            int pos2 = offset + 49 + fieldOffset2;
            pos2 += BuilderToolBlockArg.computeBytesConsumed(buf, pos2);
            if (pos2 - offset > maxEnd) {
                maxEnd = pos2 - offset;
            }
        }
        if ((nullBits[1] & 0x2) != 0x0) {
            final int fieldOffset3 = buf.getIntLE(offset + 41);
            int pos3 = offset + 49 + fieldOffset3;
            pos3 += BuilderToolMaskArg.computeBytesConsumed(buf, pos3);
            if (pos3 - offset > maxEnd) {
                maxEnd = pos3 - offset;
            }
        }
        if ((nullBits[1] & 0x4) != 0x0) {
            final int fieldOffset4 = buf.getIntLE(offset + 45);
            int pos4 = offset + 49 + fieldOffset4;
            pos4 += BuilderToolOptionArg.computeBytesConsumed(buf, pos4);
            if (pos4 - offset > maxEnd) {
                maxEnd = pos4 - offset;
            }
        }
        return maxEnd;
    }
    
    public void serialize(@Nonnull final ByteBuf buf) {
        final int startPos = buf.writerIndex();
        final byte[] nullBits = new byte[2];
        if (this.boolArg != null) {
            final byte[] array = nullBits;
            final int n = 0;
            array[n] |= 0x1;
        }
        if (this.floatArg != null) {
            final byte[] array2 = nullBits;
            final int n2 = 0;
            array2[n2] |= 0x2;
        }
        if (this.intArg != null) {
            final byte[] array3 = nullBits;
            final int n3 = 0;
            array3[n3] |= 0x4;
        }
        if (this.brushShapeArg != null) {
            final byte[] array4 = nullBits;
            final int n4 = 0;
            array4[n4] |= 0x8;
        }
        if (this.brushOriginArg != null) {
            final byte[] array5 = nullBits;
            final int n5 = 0;
            array5[n5] |= 0x10;
        }
        if (this.brushAxisArg != null) {
            final byte[] array6 = nullBits;
            final int n6 = 0;
            array6[n6] |= 0x20;
        }
        if (this.rotationArg != null) {
            final byte[] array7 = nullBits;
            final int n7 = 0;
            array7[n7] |= 0x40;
        }
        if (this.stringArg != null) {
            final byte[] array8 = nullBits;
            final int n8 = 0;
            array8[n8] |= (byte)128;
        }
        if (this.blockArg != null) {
            final byte[] array9 = nullBits;
            final int n9 = 1;
            array9[n9] |= 0x1;
        }
        if (this.maskArg != null) {
            final byte[] array10 = nullBits;
            final int n10 = 1;
            array10[n10] |= 0x2;
        }
        if (this.optionArg != null) {
            final byte[] array11 = nullBits;
            final int n11 = 1;
            array11[n11] |= 0x4;
        }
        buf.writeBytes(nullBits);
        buf.writeByte(this.required ? 1 : 0);
        buf.writeByte(this.argType.getValue());
        if (this.boolArg != null) {
            this.boolArg.serialize(buf);
        }
        else {
            buf.writeZero(1);
        }
        if (this.floatArg != null) {
            this.floatArg.serialize(buf);
        }
        else {
            buf.writeZero(12);
        }
        if (this.intArg != null) {
            this.intArg.serialize(buf);
        }
        else {
            buf.writeZero(12);
        }
        if (this.brushShapeArg != null) {
            this.brushShapeArg.serialize(buf);
        }
        else {
            buf.writeZero(1);
        }
        if (this.brushOriginArg != null) {
            this.brushOriginArg.serialize(buf);
        }
        else {
            buf.writeZero(1);
        }
        if (this.brushAxisArg != null) {
            this.brushAxisArg.serialize(buf);
        }
        else {
            buf.writeZero(1);
        }
        if (this.rotationArg != null) {
            this.rotationArg.serialize(buf);
        }
        else {
            buf.writeZero(1);
        }
        final int stringArgOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int blockArgOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int maskArgOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int optionArgOffsetSlot = buf.writerIndex();
        buf.writeIntLE(0);
        final int varBlockStart = buf.writerIndex();
        if (this.stringArg != null) {
            buf.setIntLE(stringArgOffsetSlot, buf.writerIndex() - varBlockStart);
            this.stringArg.serialize(buf);
        }
        else {
            buf.setIntLE(stringArgOffsetSlot, -1);
        }
        if (this.blockArg != null) {
            buf.setIntLE(blockArgOffsetSlot, buf.writerIndex() - varBlockStart);
            this.blockArg.serialize(buf);
        }
        else {
            buf.setIntLE(blockArgOffsetSlot, -1);
        }
        if (this.maskArg != null) {
            buf.setIntLE(maskArgOffsetSlot, buf.writerIndex() - varBlockStart);
            this.maskArg.serialize(buf);
        }
        else {
            buf.setIntLE(maskArgOffsetSlot, -1);
        }
        if (this.optionArg != null) {
            buf.setIntLE(optionArgOffsetSlot, buf.writerIndex() - varBlockStart);
            this.optionArg.serialize(buf);
        }
        else {
            buf.setIntLE(optionArgOffsetSlot, -1);
        }
    }
    
    public int computeSize() {
        int size = 49;
        if (this.stringArg != null) {
            size += this.stringArg.computeSize();
        }
        if (this.blockArg != null) {
            size += this.blockArg.computeSize();
        }
        if (this.maskArg != null) {
            size += this.maskArg.computeSize();
        }
        if (this.optionArg != null) {
            size += this.optionArg.computeSize();
        }
        return size;
    }
    
    public static ValidationResult validateStructure(@Nonnull final ByteBuf buffer, final int offset) {
        if (buffer.readableBytes() - offset < 49) {
            return ValidationResult.error("Buffer too small: expected at least 49 bytes");
        }
        final byte[] nullBits = PacketIO.readBytes(buffer, offset, 2);
        if ((nullBits[0] & 0x80) != 0x0) {
            final int stringArgOffset = buffer.getIntLE(offset + 33);
            if (stringArgOffset < 0) {
                return ValidationResult.error("Invalid offset for StringArg");
            }
            int pos = offset + 49 + stringArgOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for StringArg");
            }
            final ValidationResult stringArgResult = BuilderToolStringArg.validateStructure(buffer, pos);
            if (!stringArgResult.isValid()) {
                return ValidationResult.error("Invalid StringArg: " + stringArgResult.error());
            }
            pos += BuilderToolStringArg.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x1) != 0x0) {
            final int blockArgOffset = buffer.getIntLE(offset + 37);
            if (blockArgOffset < 0) {
                return ValidationResult.error("Invalid offset for BlockArg");
            }
            int pos = offset + 49 + blockArgOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for BlockArg");
            }
            final ValidationResult blockArgResult = BuilderToolBlockArg.validateStructure(buffer, pos);
            if (!blockArgResult.isValid()) {
                return ValidationResult.error("Invalid BlockArg: " + blockArgResult.error());
            }
            pos += BuilderToolBlockArg.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x2) != 0x0) {
            final int maskArgOffset = buffer.getIntLE(offset + 41);
            if (maskArgOffset < 0) {
                return ValidationResult.error("Invalid offset for MaskArg");
            }
            int pos = offset + 49 + maskArgOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for MaskArg");
            }
            final ValidationResult maskArgResult = BuilderToolMaskArg.validateStructure(buffer, pos);
            if (!maskArgResult.isValid()) {
                return ValidationResult.error("Invalid MaskArg: " + maskArgResult.error());
            }
            pos += BuilderToolMaskArg.computeBytesConsumed(buffer, pos);
        }
        if ((nullBits[1] & 0x4) != 0x0) {
            final int optionArgOffset = buffer.getIntLE(offset + 45);
            if (optionArgOffset < 0) {
                return ValidationResult.error("Invalid offset for OptionArg");
            }
            int pos = offset + 49 + optionArgOffset;
            if (pos >= buffer.writerIndex()) {
                return ValidationResult.error("Offset out of bounds for OptionArg");
            }
            final ValidationResult optionArgResult = BuilderToolOptionArg.validateStructure(buffer, pos);
            if (!optionArgResult.isValid()) {
                return ValidationResult.error("Invalid OptionArg: " + optionArgResult.error());
            }
            pos += BuilderToolOptionArg.computeBytesConsumed(buffer, pos);
        }
        return ValidationResult.OK;
    }
    
    public BuilderToolArg clone() {
        final BuilderToolArg copy = new BuilderToolArg();
        copy.required = this.required;
        copy.argType = this.argType;
        copy.boolArg = ((this.boolArg != null) ? this.boolArg.clone() : null);
        copy.floatArg = ((this.floatArg != null) ? this.floatArg.clone() : null);
        copy.intArg = ((this.intArg != null) ? this.intArg.clone() : null);
        copy.stringArg = ((this.stringArg != null) ? this.stringArg.clone() : null);
        copy.blockArg = ((this.blockArg != null) ? this.blockArg.clone() : null);
        copy.maskArg = ((this.maskArg != null) ? this.maskArg.clone() : null);
        copy.brushShapeArg = ((this.brushShapeArg != null) ? this.brushShapeArg.clone() : null);
        copy.brushOriginArg = ((this.brushOriginArg != null) ? this.brushOriginArg.clone() : null);
        copy.brushAxisArg = ((this.brushAxisArg != null) ? this.brushAxisArg.clone() : null);
        copy.rotationArg = ((this.rotationArg != null) ? this.rotationArg.clone() : null);
        copy.optionArg = ((this.optionArg != null) ? this.optionArg.clone() : null);
        return copy;
    }
    
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof final BuilderToolArg other) {
            return this.required == other.required && Objects.equals(this.argType, other.argType) && Objects.equals(this.boolArg, other.boolArg) && Objects.equals(this.floatArg, other.floatArg) && Objects.equals(this.intArg, other.intArg) && Objects.equals(this.stringArg, other.stringArg) && Objects.equals(this.blockArg, other.blockArg) && Objects.equals(this.maskArg, other.maskArg) && Objects.equals(this.brushShapeArg, other.brushShapeArg) && Objects.equals(this.brushOriginArg, other.brushOriginArg) && Objects.equals(this.brushAxisArg, other.brushAxisArg) && Objects.equals(this.rotationArg, other.rotationArg) && Objects.equals(this.optionArg, other.optionArg);
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(this.required, this.argType, this.boolArg, this.floatArg, this.intArg, this.stringArg, this.blockArg, this.maskArg, this.brushShapeArg, this.brushOriginArg, this.brushAxisArg, this.rotationArg, this.optionArg);
    }
}
