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

package io.netty.handler.codec.http;

import java.util.Calendar;
import io.netty.handler.codec.DateFormatter;
import java.util.Date;
import io.netty.handler.codec.CharSequenceValueConverter;
import java.util.Set;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.List;
import io.netty.handler.codec.HeadersUtils;
import io.netty.handler.codec.Headers;
import io.netty.handler.codec.ValueConverter;
import io.netty.util.HashingStrategy;
import io.netty.handler.codec.DefaultHeadersImpl;
import io.netty.util.AsciiString;
import io.netty.handler.codec.DefaultHeaders;

public class DefaultHttpHeaders extends HttpHeaders
{
    private final DefaultHeaders<CharSequence, CharSequence, ?> headers;
    
    public DefaultHttpHeaders() {
        this(nameValidator(true), valueValidator(true));
    }
    
    @Deprecated
    public DefaultHttpHeaders(final boolean validate) {
        this(nameValidator(validate), valueValidator(validate));
    }
    
    protected DefaultHttpHeaders(final boolean validateValues, final DefaultHeaders.NameValidator<CharSequence> nameValidator) {
        this(nameValidator, valueValidator(validateValues));
    }
    
    protected DefaultHttpHeaders(final DefaultHeaders.NameValidator<CharSequence> nameValidator, final DefaultHeaders.ValueValidator<CharSequence> valueValidator) {
        this(nameValidator, valueValidator, 16);
    }
    
    protected DefaultHttpHeaders(final DefaultHeaders.NameValidator<CharSequence> nameValidator, final DefaultHeaders.ValueValidator<CharSequence> valueValidator, final int sizeHint) {
        this((DefaultHeaders<CharSequence, CharSequence, ?>)new DefaultHeadersImpl((HashingStrategy<Object>)AsciiString.CASE_INSENSITIVE_HASHER, (ValueConverter<Object>)HeaderValueConverter.INSTANCE, (DefaultHeaders.NameValidator<Object>)nameValidator, sizeHint, (DefaultHeaders.ValueValidator<Object>)valueValidator));
    }
    
    protected DefaultHttpHeaders(final DefaultHeaders<CharSequence, CharSequence, ?> headers) {
        this.headers = headers;
    }
    
    public Headers<CharSequence, CharSequence, ?> unwrap() {
        return this.headers;
    }
    
    @Override
    public HttpHeaders add(final HttpHeaders headers) {
        if (headers instanceof DefaultHttpHeaders) {
            this.headers.add(((DefaultHttpHeaders)headers).headers);
            return this;
        }
        return super.add(headers);
    }
    
    @Override
    public HttpHeaders set(final HttpHeaders headers) {
        if (headers instanceof DefaultHttpHeaders) {
            this.headers.set(((DefaultHttpHeaders)headers).headers);
            return this;
        }
        return super.set(headers);
    }
    
    @Override
    public HttpHeaders add(final String name, final Object value) {
        this.headers.addObject(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders add(final CharSequence name, final Object value) {
        this.headers.addObject(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders add(final String name, final Iterable<?> values) {
        this.headers.addObject(name, values);
        return this;
    }
    
    @Override
    public HttpHeaders add(final CharSequence name, final Iterable<?> values) {
        this.headers.addObject(name, values);
        return this;
    }
    
    @Override
    public HttpHeaders addInt(final CharSequence name, final int value) {
        this.headers.addInt(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders addShort(final CharSequence name, final short value) {
        this.headers.addShort(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders remove(final String name) {
        this.headers.remove(name);
        return this;
    }
    
    @Override
    public HttpHeaders remove(final CharSequence name) {
        this.headers.remove(name);
        return this;
    }
    
    @Override
    public HttpHeaders set(final String name, final Object value) {
        this.headers.setObject(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders set(final CharSequence name, final Object value) {
        this.headers.setObject(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders set(final String name, final Iterable<?> values) {
        this.headers.setObject(name, values);
        return this;
    }
    
    @Override
    public HttpHeaders set(final CharSequence name, final Iterable<?> values) {
        this.headers.setObject(name, values);
        return this;
    }
    
    @Override
    public HttpHeaders setInt(final CharSequence name, final int value) {
        this.headers.setInt(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders setShort(final CharSequence name, final short value) {
        this.headers.setShort(name, value);
        return this;
    }
    
    @Override
    public HttpHeaders clear() {
        this.headers.clear();
        return this;
    }
    
    @Override
    public String get(final String name) {
        return this.get((CharSequence)name);
    }
    
    @Override
    public String get(final CharSequence name) {
        return HeadersUtils.getAsString(this.headers, name);
    }
    
    @Override
    public Integer getInt(final CharSequence name) {
        return this.headers.getInt(name);
    }
    
    @Override
    public int getInt(final CharSequence name, final int defaultValue) {
        return this.headers.getInt(name, defaultValue);
    }
    
    @Override
    public Short getShort(final CharSequence name) {
        return this.headers.getShort(name);
    }
    
    @Override
    public short getShort(final CharSequence name, final short defaultValue) {
        return this.headers.getShort(name, defaultValue);
    }
    
    @Override
    public Long getTimeMillis(final CharSequence name) {
        return this.headers.getTimeMillis(name);
    }
    
    @Override
    public long getTimeMillis(final CharSequence name, final long defaultValue) {
        return this.headers.getTimeMillis(name, defaultValue);
    }
    
    @Override
    public List<String> getAll(final String name) {
        return this.getAll((CharSequence)name);
    }
    
    @Override
    public List<String> getAll(final CharSequence name) {
        return HeadersUtils.getAllAsString(this.headers, name);
    }
    
    @Override
    public List<Map.Entry<String, String>> entries() {
        if (this.isEmpty()) {
            return Collections.emptyList();
        }
        final List<Map.Entry<String, String>> entriesConverted = new ArrayList<Map.Entry<String, String>>(this.headers.size());
        for (final Map.Entry<String, String> entry : this) {
            entriesConverted.add(entry);
        }
        return entriesConverted;
    }
    
    @Deprecated
    @Override
    public Iterator<Map.Entry<String, String>> iterator() {
        return HeadersUtils.iteratorAsString(this.headers);
    }
    
    @Override
    public Iterator<Map.Entry<CharSequence, CharSequence>> iteratorCharSequence() {
        return this.headers.iterator();
    }
    
    @Override
    public Iterator<String> valueStringIterator(final CharSequence name) {
        final Iterator<CharSequence> itr = this.valueCharSequenceIterator(name);
        return new Iterator<String>() {
            @Override
            public boolean hasNext() {
                return itr.hasNext();
            }
            
            @Override
            public String next() {
                return itr.next().toString();
            }
            
            @Override
            public void remove() {
                itr.remove();
            }
        };
    }
    
    @Override
    public Iterator<CharSequence> valueCharSequenceIterator(final CharSequence name) {
        return this.headers.valueIterator(name);
    }
    
    @Override
    public boolean contains(final String name) {
        return this.contains((CharSequence)name);
    }
    
    @Override
    public boolean contains(final CharSequence name) {
        return this.headers.contains(name);
    }
    
    @Override
    public boolean isEmpty() {
        return this.headers.isEmpty();
    }
    
    @Override
    public int size() {
        return this.headers.size();
    }
    
    @Override
    public boolean contains(final String name, final String value, final boolean ignoreCase) {
        return this.contains(name, (CharSequence)value, ignoreCase);
    }
    
    @Override
    public boolean contains(final CharSequence name, final CharSequence value, final boolean ignoreCase) {
        return this.headers.contains(name, value, ignoreCase ? AsciiString.CASE_INSENSITIVE_HASHER : AsciiString.CASE_SENSITIVE_HASHER);
    }
    
    @Override
    public Set<String> names() {
        return HeadersUtils.namesAsString(this.headers);
    }
    
    @Override
    public boolean equals(final Object o) {
        return o instanceof DefaultHttpHeaders && this.headers.equals(((DefaultHttpHeaders)o).headers, AsciiString.CASE_SENSITIVE_HASHER);
    }
    
    @Override
    public int hashCode() {
        return this.headers.hashCode(AsciiString.CASE_SENSITIVE_HASHER);
    }
    
    @Override
    public HttpHeaders copy() {
        return new DefaultHttpHeaders(this.headers.copy());
    }
    
    static ValueConverter<CharSequence> valueConverter() {
        return HeaderValueConverter.INSTANCE;
    }
    
    static DefaultHeaders.ValueValidator<CharSequence> valueValidator(final boolean validate) {
        return validate ? DefaultHttpHeadersFactory.headersFactory().getValueValidator() : DefaultHttpHeadersFactory.headersFactory().withValidation(false).getValueValidator();
    }
    
    static DefaultHeaders.NameValidator<CharSequence> nameValidator(final boolean validate) {
        return validate ? DefaultHttpHeadersFactory.headersFactory().getNameValidator() : DefaultHttpHeadersFactory.headersFactory().withNameValidation(false).getNameValidator();
    }
    
    private static class HeaderValueConverter extends CharSequenceValueConverter
    {
        static final HeaderValueConverter INSTANCE;
        
        @Override
        public CharSequence convertObject(final Object value) {
            if (value instanceof CharSequence) {
                return (CharSequence)value;
            }
            if (value instanceof Date) {
                return DateFormatter.format((Date)value);
            }
            if (value instanceof Calendar) {
                return DateFormatter.format(((Calendar)value).getTime());
            }
            return value.toString();
        }
        
        static {
            INSTANCE = new HeaderValueConverter();
        }
    }
}
