/* UtilLib_Servlet - Copyright (c) 2008-2017 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.servlets;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import net.mapeadores.util.request.FileValue;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.text.UTF8Bridge;


/**
 *
 * @author Vincent Calame
 */
public class HttpServletRequestMap implements RequestMap {

    protected HttpServletRequest request;
    protected UTF8Bridge utf8Bridge;
    private Map<String, Object> multiPartValueMap;
    private boolean xmlHttpRequest = false;

    public HttpServletRequestMap(HttpServletRequest request) {
        this(request, null);
    }

    public HttpServletRequestMap(HttpServletRequest request, MultiPartParser multiPartParser) {
        this.request = request;
        utf8Bridge = new UTF8Bridge(request.getCharacterEncoding());
        if (multiPartParser != null) {
            if (multiPartParser.isMultiPartContentRequest(request)) {
                this.multiPartValueMap = multiPartParser.parseMultiPartContentRequest(request);
            }
        }
        String xmlHttpRequestHeader = request.getHeader("X-Requested-With");
        if ((xmlHttpRequestHeader != null) && (xmlHttpRequestHeader.equals("XMLHttpRequest"))) {
            xmlHttpRequest = true;
        }
    }

    @Override
    public FileValue getFileValue(String name) {
        if (multiPartValueMap != null) {
            Object obj = multiPartValueMap.get(name);
            if (obj instanceof FileValue) {
                return (FileValue) obj;
            } else if (obj instanceof FileValue[]) {
                FileValue[] result = (FileValue[]) obj;
                return result[0];
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    @Override
    public FileValue[] getFileValues(String name) {
        if (multiPartValueMap != null) {
            Object obj = multiPartValueMap.get(name);
            if (obj instanceof FileValue) {
                FileValue[] result = new FileValue[1];
                result[0] = (FileValue) obj;
                return result;
            } else if (obj instanceof FileValue[]) {
                return ((FileValue[]) obj);
            } else {
                return null;
            }
        } else {
            return null;
        }
    }

    @Override
    public Object getSourceObject() {
        return request;
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    @Override
    public String getParameter(String name) {
        if (multiPartValueMap != null) {
            Object obj = multiPartValueMap.get(name);
            if (obj instanceof String) {
                return (String) obj;
            }
            if (obj instanceof String[]) {
                return ((String[]) obj)[0];
            } else {
                return null;
            }
        } else {
            return utf8Bridge.toUTF8(request.getParameter(name));

        }
    }

    @Override
    public String[] getParameterValues(String name) {
        if (multiPartValueMap != null) {
            Object obj = multiPartValueMap.get(name);
            if (obj instanceof String) {
                String[] result = new String[1];
                result[0] = (String) obj;
                return result;
            }
            if (obj instanceof String[]) {
                return ((String[]) obj);
            } else {
                return null;
            }
        } else {
            String[] paramValues = request.getParameterValues(name);
            if (paramValues == null) {
                return null;
            }
            int length = paramValues.length;
            String[] result = new String[length];
            for (int i = 0; i < length; i++) {
                result[i] = utf8Bridge.toUTF8(paramValues[i]);
            }
            return result;
        }
    }

    @Override
    public Set<String> getParameterNameSet() {
        Set<String> hashSet = new HashSet<String>();
        if (multiPartValueMap != null) {
            hashSet.addAll(multiPartValueMap.keySet());
        } else {
            for (Enumeration enumeration = request.getParameterNames(); enumeration.hasMoreElements();) {
                String paramName = (String) enumeration.nextElement();
                hashSet.add(paramName);
            }
        }
        return hashSet;
    }

    public boolean isXMLHttpRequest() {
        return xmlHttpRequest;
    }

    @Override
    public Locale[] getAcceptableLocaleArray() {
        List<Locale> localeList = new ArrayList<Locale>();
        for (Enumeration enumeration = request.getLocales(); enumeration.hasMoreElements();) {
            Locale locale = (Locale) enumeration.nextElement();
            localeList.add(locale);
        }
        return localeList.toArray(new Locale[localeList.size()]);
    }

}
