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

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

import com.hypixel.hytale.protocol.io.netty.ProtocolUtil;
import java.util.logging.Level;
import io.netty.channel.ChannelHandlerContext;
import com.hypixel.hytale.logger.HytaleLogger;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class RateLimitHandler extends ChannelInboundHandlerAdapter
{
    private static final HytaleLogger LOGGER;
    private final int maxTokens;
    private final int refillRate;
    private int tokens;
    private long lastRefillTime;
    
    public RateLimitHandler(final int maxTokens, final int refillRate) {
        this.maxTokens = maxTokens;
        this.refillRate = refillRate;
        this.tokens = maxTokens;
        this.lastRefillTime = System.nanoTime();
    }
    
    private void refillTokens() {
        final long now = System.nanoTime();
        final long elapsedNanos = now - this.lastRefillTime;
        final long tokensToAdd = elapsedNanos * this.refillRate / 1000000000L;
        if (tokensToAdd > 0L) {
            this.tokens = (int)Math.min(this.maxTokens, this.tokens + tokensToAdd);
            this.lastRefillTime = now;
        }
    }
    
    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
        this.refillTokens();
        if (this.tokens > 0) {
            --this.tokens;
            ctx.fireChannelRead(msg);
        }
        else {
            RateLimitHandler.LOGGER.at(Level.WARNING).log("Rate limit exceeded for %s, disconnecting", NettyUtil.formatRemoteAddress(ctx.channel()));
            ProtocolUtil.closeApplicationConnection(ctx.channel(), 1);
        }
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
    }
}
