package com.jscape.inet.http.protocol.messages;

import java.util.*;

import static com.jscape.util.Parameters.assertNotNull;

/**
 * @author Alex Usun
 */
public class Headers
        implements Iterable<Header> {
    
    private List<Header> entries;
    
    public Headers(List<Header> entries) {
        this.entries = new ArrayList<>(entries);
    }
    
    public Headers(Header... entries) {
        this(Arrays.asList(entries));
    }
    
    public Headers(Headers that) {
        this(that.entries);
    }
    
    @Override
    public Iterator<Header> iterator() {
        return this.entries.iterator();
    }
    
    public boolean contains(String header) {
        return lastIndexOf(header) != -1;
    }
    
    public String valueOf(String header) {
        int index = lastIndexOf(header);
        return index != -1 ? this.entries.get(index).value : null;
    }
    
    public Integer intValueOf(String header, int radix) {
        int index = lastIndexOf(header);
        return index != -1 ? this.entries.get(index).intValue(radix) : null;
    }
    
    public Long longValueOf(String header, int radix) {
        int index = lastIndexOf(header);
        return index != -1 ? this.entries.get(index).longValue(radix) : null;
    }

    public Headers add(Header header) {
        assertNotNull(header);
        this.entries.add(header);
        return this;
    }

    public Headers add(String header, String value) {
        return add(new Header(header, value));
    }

    public Headers set(String header, String value) {
        return set(new Header(header, value));
    }

    public Headers set(Header header) {
        int index = lastIndexOf(header.name);
    
        if (index != -1) {
            this.entries.remove(index);
            this.entries.add(index, header);
        } else {
            this.entries.add(header);
        }

        return this;
    }
    
    public Header[] toArray() {
        return this.entries.toArray(new Header[0]);
    }
    
    public Map<String, List<String>> toMap() {
        Map<String, List<String>> map = new HashMap<>();
        for (Header entry : this.entries) {
            List<String> values = map.get(entry.name);
            
            if (values == null) {
                values = new ArrayList<>();
            }
    
            values.add(entry.value);
        }
        
        return map;
    }
    
    @Override
    public String toString() {
        return "Headers {"
               + "entries=" + this.entries
               + '}';
    }
    
    public int lastIndexOf(String header) {
        for (int i = this.entries.size() - 1; i >= 0; --i) {
            Header entry = this.entries.get(i);
            if (entry.name.equalsIgnoreCase(header)) {
                return i;
            }
        }
        
        return -1;
    }
}
