package fineuploader;

import org.apache.commons.fileupload.FileItem;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.tagext.IterationTag;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class RequestParser
{
    private static String FILENAME_PARAM = "qqfile";
    private static String PART_INDEX_PARAM = "qqpartindex";
    private static String FILE_SIZE_PARAM = "qqtotalfilesize";
    private static String TOTAL_PARTS_PARAM = "qqtotalparts";
    private static String UUID_PARAM = "qquuid";
    private static String PART_FILENAME_PARAM = "qqfilename";

    private static String GENERATE_ERROR_PARAM = "generateError";

    private String filename;
    private FileItem uploadItem;
    private boolean generateError;

    private int partIndex = -1;
    private int totalFileSize;
    private int totalParts;
    private String uuid;
    private String originalFilename;

    private Map<String, String> customParams = new HashMap<>();


    private RequestParser()
    {
    }

    //2nd param is null unless a MPFR
    static RequestParser getInstance(HttpServletRequest request, MultipartUploadParser multipartUploadParser) throws Exception
    {
        RequestParser requestParser = new RequestParser();

        if (multipartUploadParser == null)
        {
            requestParser.filename = request.getParameter(FILENAME_PARAM);
            parseQueryStringParams(requestParser, request);
        }
        else
        {
            requestParser.uploadItem = multipartUploadParser.getFirstFile();
            requestParser.filename = multipartUploadParser.getFirstFile().getName();

            //params could be in body or query string, depending on Fine Uploader request option properties
            parseRequestBodyParams(requestParser, multipartUploadParser);
            parseQueryStringParams(requestParser, request);
        }

        removeQqParams(requestParser.customParams);

        return requestParser;
    }

    public String getFilename()
    {
        return filename;
    }

    //only non-null for MPFRs
    public FileItem getUploadItem()
    {
        return uploadItem;
    }

    public boolean generateError()
    {
        return generateError;
    }

    public int getPartIndex()
    {
        return partIndex;
    }

    public int getTotalFileSize()
    {
        return totalFileSize;
    }

    public int getTotalParts()
    {
        return totalParts;
    }

    public String getUuid()
    {
        return uuid;
    }

    public String getOriginalFilename()
    {
        return originalFilename;
    }

    public Map<String, String> getCustomParams()
    {
        return customParams;
    }

    private static void parseRequestBodyParams(RequestParser requestParser, MultipartUploadParser multipartUploadParser) throws Exception
    {
        if (multipartUploadParser.getParams().get(GENERATE_ERROR_PARAM) != null)
        {
            requestParser.generateError = Boolean.parseBoolean(multipartUploadParser.getParams().get(GENERATE_ERROR_PARAM));
        }

        String partNumStr = multipartUploadParser.getParams().get(PART_INDEX_PARAM);
        if (partNumStr != null)
        {
            requestParser.partIndex = Integer.parseInt(partNumStr);

            requestParser.totalFileSize = Integer.parseInt(multipartUploadParser.getParams().get(FILE_SIZE_PARAM));
            requestParser.totalParts = Integer.parseInt(multipartUploadParser.getParams().get(TOTAL_PARTS_PARAM));
            requestParser.uuid = multipartUploadParser.getParams().get(UUID_PARAM);
            requestParser.originalFilename = URLDecoder.decode(multipartUploadParser.getParams().get(PART_FILENAME_PARAM), "UTF-8");
        }

        for (Map.Entry<String, String> paramEntry : multipartUploadParser.getParams().entrySet())
        {
            requestParser.customParams.put(URLDecoder.decode(paramEntry.getKey(), "UTF-8"), URLDecoder.decode(paramEntry.getValue(), "UTF-8"));
        }
    }

    private static void parseQueryStringParams(RequestParser requestParser, HttpServletRequest req)
    {
        if (req.getParameter(GENERATE_ERROR_PARAM) != null)
        {
            requestParser.generateError = Boolean.parseBoolean(req.getParameter(GENERATE_ERROR_PARAM));
        }

        String partNumStr = req.getParameter(PART_INDEX_PARAM);
        if (partNumStr != null)
        {
            requestParser.partIndex = Integer.parseInt(partNumStr);
            requestParser.totalFileSize = Integer.parseInt(req.getParameter(FILE_SIZE_PARAM));
            requestParser.totalParts = Integer.parseInt(req.getParameter(TOTAL_PARTS_PARAM));
            requestParser.uuid = req.getParameter(UUID_PARAM);
            requestParser.originalFilename = req.getParameter(PART_FILENAME_PARAM);
        }

        Enumeration<String> paramNames = req.getParameterNames();
        while (paramNames.hasMoreElements())
        {
            String paramName = paramNames.nextElement();
            requestParser.customParams.put(paramName, req.getParameter(paramName));
        }
    }

    private static void removeQqParams(Map<String, String> customParams)
    {
        Iterator<Map.Entry<String, String>> paramIterator = customParams.entrySet().iterator();

        while (paramIterator.hasNext())
        {
            Map.Entry<String, String> paramEntry = paramIterator.next();
            if (paramEntry.getKey().startsWith("qq"))
            {
                paramIterator.remove();
            }
        }
    }
}

@@ -3565,92 +3565,8 @@
 ));%0A
-            requestParser.uuid = multipartUploadParser.getParams().get(UUID_PARAM);%0A
     
@@ -3694,16 +3694,16 @@
 TF-8%22);%0A
+
         
@@ -3959,32 +3959,178 @@
 8%22));%0A        %7D%0A
+%0A        if (requestParser.uuid == null)%0A        %7B%0A            requestParser.uuid = multipartUploadParser.getParams().get(UUID_PARAM);%0A        %7D%0A%0A
     %7D%0A%0A    priva
@@ -4778,71 +4778,8 @@
 ));%0A
-            requestParser.uuid = req.getParameter(UUID_PARAM);%0A
     
@@ -5043,24 +5043,24 @@
 tElement();%0A
-
             
@@ -5136,24 +5136,148 @@
 );%0A        %7D
+%0A%0A        if (requestParser.uuid == null)%0A        %7B%0A            requestParser.uuid = req.getParameter(UUID_PARAM);%0A        %7D
 %0A    %7D%0A%0A    

fix uuid parsing in java test request parser