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

package io.netty.handler.codec.http3;

import java.util.AbstractMap;
import java.util.Iterator;
import io.netty.util.internal.ObjectUtil;
import javax.annotation.Nullable;
import io.netty.util.collection.LongObjectHashMap;
import io.netty.util.collection.LongObjectMap;
import java.util.Map;

public final class Http3Settings implements Iterable<Map.Entry<Long, Long>>
{
    private final LongObjectMap<Long> settings;
    private static final Long TRUE;
    private static final Long FALSE;
    
    public Http3Settings() {
        this.settings = new LongObjectHashMap<Long>(Http3SettingIdentifier.values().length);
    }
    
    Http3Settings(final int initialCapacity) {
        this.settings = new LongObjectHashMap<Long>(initialCapacity);
    }
    
    Http3Settings(final int initialCapacity, final float loadFactor) {
        this.settings = new LongObjectHashMap<Long>(initialCapacity, loadFactor);
    }
    
    @Nullable
    public Long put(final long key, final Long value) {
        if (Http3CodecUtils.isReservedHttp2Setting(key)) {
            throw new IllegalArgumentException("Setting is reserved for HTTP/2: " + key);
        }
        final Http3SettingIdentifier identifier = Http3SettingIdentifier.fromId(key);
        if (identifier == null) {
            return null;
        }
        verifyStandardSetting(identifier, value);
        return this.settings.put(key, value);
    }
    
    @Nullable
    public Long get(final long key) {
        return this.settings.get(key);
    }
    
    @Nullable
    public Long qpackMaxTableCapacity() {
        return this.get(Http3SettingIdentifier.HTTP3_SETTINGS_QPACK_MAX_TABLE_CAPACITY.id());
    }
    
    public Http3Settings qpackMaxTableCapacity(final long value) {
        this.put(Http3SettingIdentifier.HTTP3_SETTINGS_QPACK_MAX_TABLE_CAPACITY.id(), value);
        return this;
    }
    
    @Nullable
    public Long maxFieldSectionSize() {
        return this.get(Http3SettingIdentifier.HTTP3_SETTINGS_MAX_FIELD_SECTION_SIZE.id());
    }
    
    public Http3Settings maxFieldSectionSize(final long value) {
        this.put(Http3SettingIdentifier.HTTP3_SETTINGS_MAX_FIELD_SECTION_SIZE.id(), value);
        return this;
    }
    
    @Nullable
    public Long qpackBlockedStreams() {
        return this.get(Http3SettingIdentifier.HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS.id());
    }
    
    public Http3Settings qpackBlockedStreams(final long value) {
        this.put(Http3SettingIdentifier.HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS.id(), value);
        return this;
    }
    
    @Nullable
    public Boolean connectProtocolEnabled() {
        final Long value = this.get(Http3SettingIdentifier.HTTP3_SETTINGS_ENABLE_CONNECT_PROTOCOL.id());
        return (value == null) ? null : Boolean.valueOf(Http3Settings.TRUE.equals(value));
    }
    
    public Http3Settings enableConnectProtocol(final boolean enabled) {
        this.put(Http3SettingIdentifier.HTTP3_SETTINGS_ENABLE_CONNECT_PROTOCOL.id(), enabled ? Http3Settings.TRUE : Http3Settings.FALSE);
        return this;
    }
    
    @Nullable
    public Boolean h3DatagramEnabled() {
        final Long value = this.get(Http3SettingIdentifier.HTTP3_SETTINGS_H3_DATAGRAM.id());
        return (value == null) ? null : Boolean.valueOf(Http3Settings.TRUE.equals(value));
    }
    
    public Http3Settings enableH3Datagram(final boolean enabled) {
        this.put(Http3SettingIdentifier.HTTP3_SETTINGS_H3_DATAGRAM.id(), enabled ? Http3Settings.TRUE : Http3Settings.FALSE);
        return this;
    }
    
    public Http3Settings putAll(final Http3Settings http3Settings) {
        ObjectUtil.checkNotNull(http3Settings, "http3Settings");
        this.settings.putAll((Map<?, ?>)http3Settings.settings);
        return this;
    }
    
    public static Http3Settings defaultSettings() {
        return new Http3Settings().qpackMaxTableCapacity(0L).qpackBlockedStreams(0L).maxFieldSectionSize(Long.MAX_VALUE).enableConnectProtocol(false).enableH3Datagram(false);
    }
    
    @Override
    public Iterator<Map.Entry<Long, Long>> iterator() {
        final Iterator<LongObjectMap.PrimitiveEntry<Long>> it = this.settings.entries().iterator();
        return new Iterator<Map.Entry<Long, Long>>() {
            @Override
            public boolean hasNext() {
                return it.hasNext();
            }
            
            @Override
            public Map.Entry<Long, Long> next() {
                final LongObjectMap.PrimitiveEntry<Long> entry = it.next();
                return new AbstractMap.SimpleImmutableEntry<Long, Long>(entry.key(), entry.value());
            }
        };
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Http3Settings)) {
            return false;
        }
        final Http3Settings that = (Http3Settings)o;
        return this.settings.equals(that.settings);
    }
    
    @Override
    public int hashCode() {
        return this.settings.hashCode();
    }
    
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("Http3Settings{");
        boolean first = true;
        for (final LongObjectMap.PrimitiveEntry<Long> e : this.settings.entries()) {
            if (!first) {
                sb.append(", ");
            }
            first = false;
            sb.append("0x").append(Long.toHexString(e.key())).append('=').append(e.value());
        }
        return sb.append('}').toString();
    }
    
    private static void verifyStandardSetting(final Http3SettingIdentifier identifier, final Long value) {
        ObjectUtil.checkNotNull(value, "value");
        ObjectUtil.checkNotNull(identifier, "identifier");
        switch (identifier) {
            case HTTP3_SETTINGS_QPACK_MAX_TABLE_CAPACITY:
            case HTTP3_SETTINGS_QPACK_BLOCKED_STREAMS:
            case HTTP3_SETTINGS_MAX_FIELD_SECTION_SIZE: {
                if (value < 0L) {
                    throw new IllegalArgumentException("Setting 0x" + Long.toHexString(identifier.id()) + " invalid: " + value + " (must be >= 0)");
                }
                break;
            }
            case HTTP3_SETTINGS_ENABLE_CONNECT_PROTOCOL:
            case HTTP3_SETTINGS_H3_DATAGRAM: {
                if (value != 0L && value != 1L) {
                    throw new IllegalArgumentException("Invalid: " + value + "for " + Http3SettingIdentifier.valueOf(String.valueOf(identifier)) + " (expected 0 or 1)");
                }
                break;
            }
            default: {
                if (value < 0L) {
                    throw new IllegalArgumentException("Setting 0x" + Long.toHexString(identifier.id()) + " invalid: " + value);
                }
                break;
            }
        }
    }
    
    static {
        TRUE = 1L;
        FALSE = 0L;
    }
}
