package com.google.step.coffee.servlets;

import com.google.step.coffee.*;
import com.google.step.coffee.data.RequestStore;
import com.google.step.coffee.entity.ChatRequest;
import com.google.step.coffee.entity.ChatRequestBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** Servlet to manage user requests for a chat. */
@WebServlet("/api/chat-request")
public class ChatRequestServlet extends JsonServlet {

  private RequestStore requestStore = new RequestStore();

  @Override
  public Object post(JsonServletRequest request) throws IOException, HttpError {
    PermissionChecker.ensureLoggedIn();

    if (OAuthService.userHasAuthorised(UserManager.getCurrentUserId())) {
      ChatRequest chatRequest = buildChatRequestFromHttpRequest(request);

      requestStore.addRequest(chatRequest);

      return "Success";
    } else {
      throw new HttpError(HttpServletResponse.SC_UNAUTHORIZED,
          "Please authorise app to schedule chat");
    }
  }

  private ChatRequest buildChatRequestFromHttpRequest(HttpServletRequest request) throws HttpError {
    List<String> tags = getParameterValues("tags", request);
    List<String> dateStrings = getParameterValues("dates", request);
    int minPeople = Integer.parseInt(getParameterOrDefault("minPeople", request, "1"));
    int maxPeople = Integer.parseInt(getParameterOrDefault("maxPeople", request, "1"));
    int durationMins = Integer.parseInt(getParameterOrDefault("durationMins", request, "30"));
    boolean matchRandom =
        Boolean.parseBoolean(getParameterOrDefault("matchRandom", request, "false"));
    boolean matchRecents =
        Boolean.parseBoolean(getParameterOrDefault("matchRecents", request, "true"));

    List<Date> dates = dateStrings.stream()
        .map(Long::parseLong)
        .map(Date::new)
        .collect(Collectors.toList());

    return new ChatRequestBuilder()
        .withTags(tags)
        .onDates(dates)
        .withGroupSize(minPeople, maxPeople)
        .withMaxChatLength(durationMins)
        .willMatchRandomlyOnFail(matchRandom)
        .willMatchWithRecents(matchRecents)
        .forUser(UserManager.getCurrentUserId())
        .build();
  }

  private String getParameterOrDefault(String name, HttpServletRequest req, String defaultValue) {
    String paramString = req.getParameter(name);
    return (paramString != null) ? paramString : defaultValue;
  }

  private List<String> getParameterValues(String name, HttpServletRequest req) {
    String paramString = req.getParameter(name);
    if (paramString == null || paramString.equals("")) {
      return new ArrayList<>();
    }

    return Arrays.asList(paramString.split(","));
  }
}

@@ -1465,32 +1465,24 @@
 eople = 
-Integer.
 parseInt
 (getPara
@@ -1473,38 +1473,21 @@
 parseInt
-(get
 Param
-eterOrDefault
 (%22minPeo
@@ -1491,38 +1491,32 @@
 People%22, request
-, %221%22)
 );%0A    int maxPe
@@ -1522,32 +1522,24 @@
 eople = 
-Integer.
 parseInt
 (getPara
@@ -1530,38 +1530,21 @@
 parseInt
-(get
 Param
-eterOrDefault
 (%22maxPeo
@@ -1560,14 +1560,8 @@
 uest
-, %221%22)
 );%0A 
@@ -1586,24 +1586,16 @@
 s = 
-Integer.
 parseInt
 (get
@@ -1590,38 +1590,21 @@
 parseInt
-(get
 Param
-eterOrDefault
 (%22durati
@@ -1623,15 +1623,8 @@
 uest
-, %2230%22)
 );%0A 
@@ -1647,33 +1647,17 @@
 Random =
-%0A        Boolean.
+ 
 parseBoo
@@ -1660,38 +1660,21 @@
 eBoolean
-(get
 Param
-eterOrDefault
 (%22matchR
@@ -1698,17 +1698,16 @@
 %22false%22)
-)
 ;%0A    bo
@@ -1730,25 +1730,9 @@
 ts =
-%0A        Boolean.
+ 
 pars
@@ -1743,30 +1743,13 @@
 lean
-(get
 Param
-eterOrDefault
 (%22ma
@@ -1777,17 +1777,16 @@
  %22true%22)
-)
 ;%0A%0A    L
@@ -2480,271 +2480,1156 @@
 ate 
-List%3CString%3E getParameterValues(String name, HttpServletRequest req) %7B%0A    String paramString = req.getParameter(name);%0A    if (paramString == null %7C%7C paramString.equals(%22%22)) %7B%0A      return new ArrayList%3C%3E();%0A    %7D%0A%0A    return Arrays.asList(paramString.split(%22,%22)
+String getParameter(String name, HttpServletRequest req) throws HttpError %7B%0A    String paramString = req.getParameter(name);%0A    if (paramString != null) %7B%0A      return paramString;%0A    %7D else %7B%0A      throw new HttpError(HttpServletResponse.SC_BAD_REQUEST, %22Missing parameter: %22 + name);%0A    %7D%0A  %7D%0A%0A  private List%3CString%3E getParameterValues(String name, HttpServletRequest req) %7B%0A    String paramString = req.getParameter(name);%0A    if (paramString == null %7C%7C paramString.equals(%22%22)) %7B%0A      return new ArrayList%3C%3E();%0A    %7D%0A%0A    return Arrays.asList(paramString.split(%22,%22));%0A  %7D%0A%0A  private Integer parseIntParam(String name, HttpServletRequest req) throws HttpError %7B%0A    String paramString = getParameter(name, req);%0A%0A    try %7B%0A      return Integer.parseInt(paramString);%0A    %7D catch (NumberFormatException e) %7B%0A      throw new HttpError(HttpServletResponse.SC_BAD_REQUEST,%0A          %22Invalid integer parameter: %22 + name);%0A    %7D%0A  %7D%0A%0A  private boolean parseBooleanParam(String name, HttpServletRequest req, String defaultValue) %7B%0A    String paramString = getParameterOrDefault(name, req, defaultValue);%0A%0A    return Boolean.parseBoolean(paramString
 );%0A 

Add error handling to ChatRequest servlet in case of missing or malformed parameters