package packets;

import game.Game;
import proxy.CompressionManager;

import javax.naming.SizeLimitExceededException;

public class DataProvider {
    private static final int MAX_SIZE = 2097152;
    private DataReader reader;
    private CompressionManager compressionManager;

    public DataProvider(DataReader reader) {
        this.reader = reader;
        this.compressionManager = Game.getCompressionManager();
    }

    /**
     * Provides the object with all the bytes from the packet, allowing them to be read into the correct data types
     * easily. This method will also decompress the packet, as this is the first time we have the full packet
     * available, which is what we need for valid decompression.
     * @param size the packet size
     * @return the data parser for the decompressed packet
     */
    public DataTypeProvider withSize(int size) throws SizeLimitExceededException {
        byte[] compressed = reader.readByteArray(size);

        byte[] fullPacket;
        if (compressionManager.isCompressionEnabled()) {
            final int[] compressionPos = {0};
            int uncompressedSize = DataReader.readVarInt(
                () -> compressionPos[0] < compressed.length,
                () -> compressed[compressionPos[0]++]
            );

            // packets over this size will crash the game client, so it may help to reject them here
            if (uncompressedSize > MAX_SIZE) {
                throw new SizeLimitExceededException("WARNING: discarding packet over maximum size (size: " + uncompressedSize + ")");
            }

            fullPacket = compressionManager.decompressPacket(compressed, compressionPos[0], uncompressedSize);
        } else {
            fullPacket = compressed;
        }

        return DataTypeProvider.ofPacket(fullPacket);
    }
}