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

package io.netty.channel.epoll;

import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.channel.ChannelConfig;
import io.netty.channel.MessageSizeEstimator;
import io.netty.channel.WriteBufferWaterMark;
import io.netty.buffer.ByteBufAllocator;
import java.io.IOException;
import io.netty.channel.ChannelException;
import java.nio.ByteBuffer;
import io.netty.channel.unix.RawUnixChannelOption;
import io.netty.channel.unix.IntegerUnixChannelOption;
import io.netty.channel.ChannelOption;
import java.util.Map;
import io.netty.channel.RecvByteBufAllocator;
import io.netty.channel.unix.Limits;
import io.netty.channel.Channel;
import io.netty.util.internal.logging.InternalLogger;
import io.netty.channel.DefaultChannelConfig;

public class EpollChannelConfig extends DefaultChannelConfig
{
    private static final InternalLogger LOGGER;
    private volatile long maxBytesPerGatheringWrite;
    
    protected EpollChannelConfig(final Channel channel) {
        super(checkAbstractEpollChannel(channel));
        this.maxBytesPerGatheringWrite = Limits.SSIZE_MAX;
    }
    
    protected EpollChannelConfig(final Channel channel, final RecvByteBufAllocator recvByteBufAllocator) {
        super(checkAbstractEpollChannel(channel), recvByteBufAllocator);
        this.maxBytesPerGatheringWrite = Limits.SSIZE_MAX;
    }
    
    protected LinuxSocket socket() {
        return ((AbstractEpollChannel)this.channel).socket;
    }
    
    private static Channel checkAbstractEpollChannel(final Channel channel) {
        if (!(channel instanceof AbstractEpollChannel)) {
            throw new IllegalArgumentException("channel is not AbstractEpollChannel: " + channel.getClass());
        }
        return channel;
    }
    
    @Override
    public Map<ChannelOption<?>, Object> getOptions() {
        return this.getOptions(super.getOptions(), EpollChannelOption.EPOLL_MODE);
    }
    
    @Override
    public <T> T getOption(final ChannelOption<T> option) {
        if (option == EpollChannelOption.EPOLL_MODE) {
            return (T)this.getEpollMode();
        }
        try {
            if (option instanceof IntegerUnixChannelOption) {
                final IntegerUnixChannelOption opt = (IntegerUnixChannelOption)option;
                return (T)Integer.valueOf(((AbstractEpollChannel)this.channel).socket.getIntOpt(opt.level(), opt.optname()));
            }
            if (option instanceof RawUnixChannelOption) {
                final RawUnixChannelOption opt2 = (RawUnixChannelOption)option;
                final ByteBuffer out = ByteBuffer.allocate(opt2.length());
                ((AbstractEpollChannel)this.channel).socket.getRawOpt(opt2.level(), opt2.optname(), out);
                return (T)out.flip();
            }
        }
        catch (final IOException e) {
            throw new ChannelException(e);
        }
        return super.getOption(option);
    }
    
    @Override
    public <T> boolean setOption(final ChannelOption<T> option, final T value) {
        this.validate(option, value);
        if (option == EpollChannelOption.EPOLL_MODE) {
            this.setEpollMode((EpollMode)value);
            return true;
        }
        try {
            if (option instanceof IntegerUnixChannelOption) {
                final IntegerUnixChannelOption opt = (IntegerUnixChannelOption)option;
                ((AbstractEpollChannel)this.channel).socket.setIntOpt(opt.level(), opt.optname(), (int)value);
                return true;
            }
            if (option instanceof RawUnixChannelOption) {
                final RawUnixChannelOption opt2 = (RawUnixChannelOption)option;
                ((AbstractEpollChannel)this.channel).socket.setRawOpt(opt2.level(), opt2.optname(), (ByteBuffer)value);
                return true;
            }
        }
        catch (final IOException e) {
            throw new ChannelException(e);
        }
        return super.setOption(option, value);
    }
    
    @Override
    public EpollChannelConfig setConnectTimeoutMillis(final int connectTimeoutMillis) {
        super.setConnectTimeoutMillis(connectTimeoutMillis);
        return this;
    }
    
    @Deprecated
    @Override
    public EpollChannelConfig setMaxMessagesPerRead(final int maxMessagesPerRead) {
        super.setMaxMessagesPerRead(maxMessagesPerRead);
        return this;
    }
    
    @Override
    public EpollChannelConfig setWriteSpinCount(final int writeSpinCount) {
        super.setWriteSpinCount(writeSpinCount);
        return this;
    }
    
    @Override
    public EpollChannelConfig setAllocator(final ByteBufAllocator allocator) {
        super.setAllocator(allocator);
        return this;
    }
    
    @Override
    public EpollChannelConfig setRecvByteBufAllocator(final RecvByteBufAllocator allocator) {
        if (!(allocator.newHandle() instanceof RecvByteBufAllocator.ExtendedHandle)) {
            throw new IllegalArgumentException("allocator.newHandle() must return an object of type: " + RecvByteBufAllocator.ExtendedHandle.class);
        }
        super.setRecvByteBufAllocator(allocator);
        return this;
    }
    
    @Override
    public EpollChannelConfig setAutoRead(final boolean autoRead) {
        super.setAutoRead(autoRead);
        return this;
    }
    
    @Deprecated
    @Override
    public EpollChannelConfig setWriteBufferHighWaterMark(final int writeBufferHighWaterMark) {
        super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
        return this;
    }
    
    @Deprecated
    @Override
    public EpollChannelConfig setWriteBufferLowWaterMark(final int writeBufferLowWaterMark) {
        super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
        return this;
    }
    
    @Override
    public EpollChannelConfig setWriteBufferWaterMark(final WriteBufferWaterMark writeBufferWaterMark) {
        super.setWriteBufferWaterMark(writeBufferWaterMark);
        return this;
    }
    
    @Override
    public EpollChannelConfig setMessageSizeEstimator(final MessageSizeEstimator estimator) {
        super.setMessageSizeEstimator(estimator);
        return this;
    }
    
    @Deprecated
    public EpollMode getEpollMode() {
        return EpollMode.LEVEL_TRIGGERED;
    }
    
    @Deprecated
    public EpollChannelConfig setEpollMode(final EpollMode mode) {
        EpollChannelConfig.LOGGER.debug("Changing the EpollMode is not supported anymore, this is just a no-op");
        return this;
    }
    
    private void checkChannelNotRegistered() {
        if (this.channel.isRegistered()) {
            throw new IllegalStateException("EpollMode can only be changed before channel is registered");
        }
    }
    
    @Override
    protected final void autoReadCleared() {
        ((AbstractEpollChannel)this.channel).clearEpollIn();
    }
    
    protected final void setMaxBytesPerGatheringWrite(final long maxBytesPerGatheringWrite) {
        this.maxBytesPerGatheringWrite = maxBytesPerGatheringWrite;
    }
    
    protected final long getMaxBytesPerGatheringWrite() {
        return this.maxBytesPerGatheringWrite;
    }
    
    static {
        LOGGER = InternalLoggerFactory.getInstance(EpollChannelConfig.class);
    }
}
