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

package com.hypixel.hytale.server.core.io.handlers;

import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.server.core.io.ProtocolVersion;
import io.netty.channel.Channel;
import javax.annotation.Nonnull;
import java.util.List;
import com.hypixel.hytale.protocol.Packet;
import java.util.function.Consumer;
import com.hypixel.hytale.server.core.io.PacketHandler;

public abstract class GenericPacketHandler extends PacketHandler
{
    private static final Consumer<Packet> EMPTY_CONSUMER;
    @Nonnull
    protected final List<SubPacketHandler> packetHandlers;
    private Consumer<Packet>[] handlers;
    
    @Nonnull
    public static Consumer<Packet>[] newHandlerArray(final int size) {
        return new Consumer[size];
    }
    
    public GenericPacketHandler(@Nonnull final Channel channel, @Nonnull final ProtocolVersion protocolVersion) {
        super(channel, protocolVersion);
        this.packetHandlers = new ObjectArrayList<SubPacketHandler>();
        this.handlers = newHandlerArray(0);
    }
    
    public void registerSubPacketHandler(final SubPacketHandler subPacketHandler) {
        this.packetHandlers.add(subPacketHandler);
    }
    
    public void registerHandler(final int packetId, @Nonnull final Consumer<Packet> handler) {
        if (packetId >= this.handlers.length) {
            final Consumer<Packet>[] newHandlers = newHandlerArray(packetId + 1);
            System.arraycopy(this.handlers, 0, newHandlers, 0, this.handlers.length);
            this.handlers = newHandlers;
        }
        this.handlers[packetId] = handler;
    }
    
    public void registerNoOpHandlers(@Nonnull final int... packetIds) {
        for (final int packetId : packetIds) {
            this.registerHandler(packetId, GenericPacketHandler.EMPTY_CONSUMER);
        }
    }
    
    @Override
    public final void accept(@Nonnull final Packet packet) {
        final int packetId = packet.getId();
        final Consumer<Packet> handler = (this.handlers.length > packetId) ? this.handlers[packetId] : null;
        if (handler != null) {
            try {
                handler.accept(packet);
                return;
            }
            catch (final Throwable e) {
                throw new RuntimeException("Could not handle packet (" + packetId + "): " + String.valueOf(packet), e);
            }
            throw new RuntimeException("No handler is registered for (" + packetId + "): " + String.valueOf(packet));
        }
        throw new RuntimeException("No handler is registered for (" + packetId + "): " + String.valueOf(packet));
    }
    
    static {
        EMPTY_CONSUMER = (packet -> {});
    }
}
