package com.alterdekim.hearthhack.util;

import com.google.protobuf.GeneratedMessageV3;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

@NoArgsConstructor
public class PegasusPacket {

    private final int TYPE_BYTES = 4;

    private final int SIZE_BYTES = 4;

    @Getter
    public int size;

    @Getter
    public int type;

    @Getter
    public int context;

    @Getter
    public Object body;

    private boolean sizeRead;

    private boolean typeRead;

    public PegasusPacket(int type, int context, Object body) {
        this.type = type;
        this.context = context;
        this.size = -1;
        this.body = body;
    }

    public PegasusPacket(int type, int context, byte[] body) {
        this.type = type;
        this.context = context;
        this.size = body.length;
        this.body = body;
    }

    public PegasusPacket(int type, int context, int size, Object body) {
        this.type = type;
        this.context = context;
        this.size = size;
        this.body = body;
    }

    public boolean IsLoaded() {
        return this.body != null;
    }

    public int Decode(byte[] bytes, int offset, int available) {
        String arg = "";
        int num = 0;
        while (num < 8 && num < available) {
            arg = arg + bytes[offset + num] + " ";
            num++;
        }
        int num2 = 0;
        if (!this.typeRead) {
            if (available < 4) return num2;
            this.type = toInt32_2(bytes, offset);
            this.typeRead = true;
            available -= 4;
            num2 += 4;
            offset += 4;
        }
        if (!this.sizeRead) {
            if (available < 4) return num2;
            this.size = toInt32_2(bytes, offset);
            this.sizeRead = true;
            available -= 4;
            num2 += 4;
            offset += 4;
        }
        if (this.body == null) {
            if (available < this.size) return num2;
            byte[] array = new byte[this.size];
            System.arraycopy(bytes, offset, array, 0, this.size);
            this.body = array;
            num2 += this.size;
        }
        return num2;
    }

    public byte[] Encode() {
        if (this.body instanceof GeneratedMessageV3) {
            GeneratedMessageV3 protoBuf = (GeneratedMessageV3) this.body;
            this.size = protoBuf.getSerializedSize();
            byte[] array = new byte[this.size + 4 + 4];
            System.arraycopy(getBytes(this.type), 0, array, 0, 4);
            System.arraycopy(getBytes(this.size), 0, array, 4, 4);
            System.arraycopy(protoBuf.toByteArray(), 0, array, 8, this.size);
            return array;
        }
        this.size = ((byte[]) this.body).length;
        byte[] array = new byte[this.size + 4 + 4];
        System.arraycopy(getBytes(this.type), 0, array, 0, 4);
        System.arraycopy(getBytes(this.size), 0, array, 4, 4);
        System.arraycopy(this.body, 0, array, 8, this.size);
        return array;
    }

    private int toInt32_2(byte[] bytes, int index) {
        int a = (int)((int)(0xff & bytes[index]) << 32 | (int)(0xff & bytes[index + 1]) << 40 | (int)(0xff & bytes[index + 2]) << 48 | (int)(0xff & bytes[index + 3]) << 56);
        return a;
    }

    private static byte[] getBytes(int value) {
        return ByteBuffer.allocate(4)
                .order(ByteOrder.nativeOrder())
                .putInt(value)
                .array();
    }
}
