package org.wikiwebserver.handler.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

public class FormData extends LinkedHashMap<String, List<String>> {

    private static final long serialVersionUID = 9055006580492754664L;
    
    public String getFirst(String key) {
        List<String> list = get(key);
        if (list == null) return null;
        return list.get(0);
    }   
    
    public void add(String key, String... values) {
        List<String> list = get(key);
        if (list == null) {
            set(key, values);
        } else {
            populate(list, values);
        }
    }
    
    public void set(String key, String... values) {
        List<String> list = new LinkedList<String>();
        populate(list, values);
        put(key, list);
    }      
    
    public void set(String key, List<String> values) {
        if (values != null) {
            List<String> list = new LinkedList<String>();
            populate(list, values);
            put(key, list);
        }
    }     
    
    private void populate(List<String> list, String... values) {
        for (String value : values) list.add(value);
    }

    private void populate(List<String> list, List<String> values) {
        for (String value : values) list.add(value);
    }
  
    public static FormData parseURLEncodedFormData(String urlEncodedFormData) 
        throws IOException {
        
        FormData formData = new FormData();
        StringTokenizer tokenizer = new StringTokenizer(urlEncodedFormData, "&");
        while (tokenizer.hasMoreTokens()) {
            String entry = tokenizer.nextToken();
            int idx = entry.indexOf('=');
            if (idx > -1) {
                String key = URLDecoder.decode(entry.substring(0, idx), "UTF8");
                String value = null;
                if (entry.length() > idx+1) {
                    value = URLDecoder.decode(entry.substring(idx+1), "UTF8");
                }
                formData.add(key, value);
            }
        }
        return formData;
    }
    
    public String getURLEncodedFormData() {
        
        try {
            StringBuilder billy = new StringBuilder(256);
            Iterator<Map.Entry<String, List<String>>> i = entrySet().iterator();
            while (i.hasNext()) {
                Map.Entry<String, List<String>> entry = i.next();
                List<String> values = entry.getValue();
                if (values == null || values.size() == 0) {
                    billy.append(entry.getKey());
                    billy.append("=");
                } else {
                    Iterator<String> vi = values.iterator();
                    while (vi.hasNext()) {
                        billy.append(URLEncoder.encode(entry.getKey(), "UTF8"));
                        billy.append("=");
                        billy.append(URLEncoder.encode(vi.next(), "UTF8"));
                        if (vi.hasNext()) {
                            billy.append("&");
                        }                        
                    }
                }
                if (i.hasNext()) {
                    billy.append("&");
                }
            }
            return billy.toString();
        }
        catch (UnsupportedEncodingException ex) {
            throw new NullPointerException(ex.getMessage());
        }        
    }         
}

