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

package io.netty.handler.codec.http3;

import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
import io.netty.util.HashingStrategy;
import io.netty.handler.codec.Headers;
import io.netty.handler.codec.ValueConverter;
import io.netty.handler.codec.CharSequenceValueConverter;
import io.netty.util.AsciiString;
import io.netty.util.ByteProcessor;
import io.netty.handler.codec.DefaultHeaders;

public final class DefaultHttp3Headers extends DefaultHeaders<CharSequence, CharSequence, Http3Headers> implements Http3Headers
{
    private static final ByteProcessor HTTP3_NAME_VALIDATOR_PROCESSOR;
    static final NameValidator<CharSequence> HTTP3_NAME_VALIDATOR;
    private HeaderEntry<CharSequence, CharSequence> firstNonPseudo;
    
    public DefaultHttp3Headers() {
        this(true);
    }
    
    public DefaultHttp3Headers(final boolean validate) {
        super(AsciiString.CASE_SENSITIVE_HASHER, (ValueConverter<Object>)CharSequenceValueConverter.INSTANCE, validate ? DefaultHttp3Headers.HTTP3_NAME_VALIDATOR : NameValidator.NOT_NULL);
        this.firstNonPseudo = (HeaderEntry<CharSequence, CharSequence>)this.head;
    }
    
    public DefaultHttp3Headers(final boolean validate, final int arraySizeHint) {
        super(AsciiString.CASE_SENSITIVE_HASHER, (ValueConverter<Object>)CharSequenceValueConverter.INSTANCE, validate ? DefaultHttp3Headers.HTTP3_NAME_VALIDATOR : NameValidator.NOT_NULL, arraySizeHint);
        this.firstNonPseudo = (HeaderEntry<CharSequence, CharSequence>)this.head;
    }
    
    @Override
    public Http3Headers clear() {
        this.firstNonPseudo = (HeaderEntry<CharSequence, CharSequence>)this.head;
        return super.clear();
    }
    
    @Override
    public boolean equals(final Object o) {
        return o instanceof Http3Headers && ((DefaultHeaders<CharSequence, CharSequence, T>)this).equals((Headers<CharSequence, CharSequence, ?>)o, AsciiString.CASE_SENSITIVE_HASHER);
    }
    
    @Override
    public int hashCode() {
        return ((DefaultHeaders<K, CharSequence, T>)this).hashCode(AsciiString.CASE_SENSITIVE_HASHER);
    }
    
    @Override
    public Http3Headers method(final CharSequence value) {
        ((DefaultHeaders<AsciiString, CharSequence, Headers>)this).set(PseudoHeaderName.METHOD.value(), value);
        return this;
    }
    
    @Override
    public Http3Headers scheme(final CharSequence value) {
        ((DefaultHeaders<AsciiString, CharSequence, Headers>)this).set(PseudoHeaderName.SCHEME.value(), value);
        return this;
    }
    
    @Override
    public Http3Headers authority(final CharSequence value) {
        ((DefaultHeaders<AsciiString, CharSequence, Headers>)this).set(PseudoHeaderName.AUTHORITY.value(), value);
        return this;
    }
    
    @Override
    public Http3Headers path(final CharSequence value) {
        ((DefaultHeaders<AsciiString, CharSequence, Headers>)this).set(PseudoHeaderName.PATH.value(), value);
        return this;
    }
    
    @Override
    public Http3Headers status(final CharSequence value) {
        ((DefaultHeaders<AsciiString, CharSequence, Headers>)this).set(PseudoHeaderName.STATUS.value(), value);
        return this;
    }
    
    @Override
    public CharSequence method() {
        return ((DefaultHeaders<AsciiString, CharSequence, T>)this).get(PseudoHeaderName.METHOD.value());
    }
    
    @Override
    public CharSequence scheme() {
        return ((DefaultHeaders<AsciiString, CharSequence, T>)this).get(PseudoHeaderName.SCHEME.value());
    }
    
    @Override
    public CharSequence authority() {
        return ((DefaultHeaders<AsciiString, CharSequence, T>)this).get(PseudoHeaderName.AUTHORITY.value());
    }
    
    @Override
    public CharSequence path() {
        return ((DefaultHeaders<AsciiString, CharSequence, T>)this).get(PseudoHeaderName.PATH.value());
    }
    
    @Override
    public CharSequence status() {
        return ((DefaultHeaders<AsciiString, CharSequence, T>)this).get(PseudoHeaderName.STATUS.value());
    }
    
    @Override
    public boolean contains(final CharSequence name, final CharSequence value) {
        return this.contains(name, value, false);
    }
    
    @Override
    public boolean contains(final CharSequence name, final CharSequence value, final boolean caseInsensitive) {
        return ((DefaultHeaders<CharSequence, CharSequence, T>)this).contains(name, value, caseInsensitive ? AsciiString.CASE_INSENSITIVE_HASHER : AsciiString.CASE_SENSITIVE_HASHER);
    }
    
    @Override
    protected HeaderEntry<CharSequence, CharSequence> newHeaderEntry(final int h, final CharSequence name, final CharSequence value, final HeaderEntry<CharSequence, CharSequence> next) {
        return new Http3HeaderEntry(h, name, value, next);
    }
    
    static {
        HTTP3_NAME_VALIDATOR_PROCESSOR = new ByteProcessor() {
            @Override
            public boolean process(final byte value) {
                return !AsciiString.isUpperCase(value);
            }
        };
        HTTP3_NAME_VALIDATOR = new NameValidator<CharSequence>() {
            @Override
            public void validateName(@Nullable final CharSequence name) {
                if (name == null || name.length() == 0) {
                    throw new Http3HeadersValidationException(String.format("empty headers are not allowed [%s]", name));
                }
                if (name instanceof AsciiString) {
                    int index;
                    try {
                        index = ((AsciiString)name).forEachByte(DefaultHttp3Headers.HTTP3_NAME_VALIDATOR_PROCESSOR);
                    }
                    catch (final Http3HeadersValidationException e) {
                        throw e;
                    }
                    catch (final Throwable t) {
                        throw new Http3HeadersValidationException(String.format("unexpected error. invalid header name [%s]", name), t);
                    }
                    if (index != -1) {
                        throw new Http3HeadersValidationException(String.format("invalid header name [%s]", name));
                    }
                }
                else {
                    for (int i = 0; i < name.length(); ++i) {
                        if (AsciiString.isUpperCase(name.charAt(i))) {
                            throw new Http3HeadersValidationException(String.format("invalid header name [%s]", name));
                        }
                    }
                }
            }
        };
    }
    
    private final class Http3HeaderEntry extends HeaderEntry<CharSequence, CharSequence>
    {
        protected Http3HeaderEntry(final int hash, final CharSequence key, final CharSequence value, final HeaderEntry<CharSequence, CharSequence> next) {
            super(hash, key);
            this.value = (V)value;
            this.next = (HeaderEntry<K, V>)next;
            if (PseudoHeaderName.hasPseudoHeaderFormat(key)) {
                this.after = (HeaderEntry<K, V>)DefaultHttp3Headers.this.firstNonPseudo;
                this.before = DefaultHttp3Headers.this.firstNonPseudo.before();
            }
            else {
                this.after = (HeaderEntry<K, V>)DefaultHttp3Headers.this.head;
                this.before = DefaultHttp3Headers.this.head.before();
                if (DefaultHttp3Headers.this.firstNonPseudo == DefaultHttp3Headers.this.head) {
                    DefaultHttp3Headers.this.firstNonPseudo = this;
                }
            }
            this.pointNeighborsToThis();
        }
        
        @Override
        protected void remove() {
            if (this == DefaultHttp3Headers.this.firstNonPseudo) {
                DefaultHttp3Headers.this.firstNonPseudo = DefaultHttp3Headers.this.firstNonPseudo.after();
            }
            super.remove();
        }
    }
}
