// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.neighborgood.servlets;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gson.Gson;
import com.google.neighborgood.Message;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/** Servlet that loads and records new message entities. */
@WebServlet("/messages")
public class MessageServlet extends HttpServlet {
  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    HttpSession session = request.getSession();
    String taskId = request.getParameter("key");
    if (taskId == null) {
      System.err.println("No task id provided");
    }

    List<Message> messages = new ArrayList<>();

    // If the current session has not included the messages related with the query task, create
    // a new attribute with key equals to taskId and value equals to a list of messages
    if (session.getAttribute(taskId) == null) {
      // Make sure that the user has already logged into his account
      UserService userService = UserServiceFactory.getUserService();
      if (!userService.isUserLoggedIn()) {
        response.sendRedirect(userService.createLoginURL("/account.jsp"));
        return;
      }

      Filter filter = new FilterPredicate("taskId", FilterOperator.EQUAL, taskId);
      Query query =
          new Query("Message").setFilter(filter).addSort("sentTime", SortDirection.ASCENDING);

      DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
      PreparedQuery results = datastore.prepare(query);

      for (Entity entity : results.asIterable()) {
        messages.add(new Message(entity));
      }

      session.setAttribute(taskId, messages);
    } else {
      messages = (List<Message>) session.getAttribute(taskId);
    }

    Gson gson = new Gson();
    String json = gson.toJson(messages);
    response.setContentType("application/json;");
    response.getWriter().println(json);
  }

  @Override
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    // First check whether the user is logged in
    UserService userService = UserServiceFactory.getUserService();

    if (!userService.isUserLoggedIn()) {
      response.sendRedirect(userService.createLoginURL("/account.jsp"));
      return;
    }

    // Get the task ID
    String taskId = request.getParameter("task-id");
    if (taskId == null) {
      System.err.println("The task id is not included");
      return;
    }

    // Get the message content
    String message = request.getParameter("msg");
    if (message == null || message.trim().equals("")) {
      System.err.println("The input message is empty");
      return;
    }

    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

    // Create a message entity to store the related information
    Entity msgEntity = new Entity("Message");
    msgEntity.setProperty("message", message);
    msgEntity.setProperty("taskId", taskId);
    msgEntity.setProperty("sender", userService.getCurrentUser().getUserId());
    msgEntity.setProperty("sentTime", System.currentTimeMillis());

    // Update the attribute stored in session
    HttpSession session = request.getSession();
    if (session.getAttribute(taskId) == null) {
      System.err.println("Illegal state of sending a message");
    } else {
      List<Message> messages = (List<Message>) session.getAttribute(taskId);
      messages.add(new Message(msgEntity));
      session.setAttribute(taskId, messages);

      // After updating the session, store the message in datastore
      datastore.put(msgEntity);
    }

    response.sendRedirect(request.getHeader("Referer"));
  }
}

@@ -1592,47 +1592,8 @@
 nse;
-%0Aimport javax.servlet.http.HttpSession;
 %0A%0A/*
@@ -1840,56 +1840,8 @@
 n %7B%0A
-    HttpSession session = request.getSession();%0A
     
@@ -1971,291 +1971,8 @@
  %7D%0A%0A
-    List%3CMessage%3E messages = new ArrayList%3C%3E();%0A%0A    // If the current session has not included the messages related with the query task, create%0A    // a new attribute with key equals to taskId and value equals to a list of messages%0A    if (session.getAttribute(taskId) == null) %7B%0A  
     
@@ -2034,18 +2034,16 @@
 account%0A
-  
     User
@@ -2097,26 +2097,24 @@
 rService();%0A
-  
     if (!use
@@ -2144,26 +2144,24 @@
 ()) %7B%0A      
-  
 response.sen
@@ -2217,26 +2217,24 @@
 p%22));%0A      
-  
 return;%0A    
@@ -2229,31 +2229,27 @@
 return;%0A    
-  
 %7D%0A%0A
-  
     Filter f
@@ -2321,18 +2321,16 @@
 d);%0A    
-  
 Query qu
@@ -2335,18 +2335,16 @@
 query =%0A
-  
         
@@ -2433,18 +2433,16 @@
 );%0A%0A    
-  
 Datastor
@@ -2513,18 +2513,16 @@
 ();%0A    
- 
- 
 Prepared
@@ -2562,24 +2562,70 @@
 (query);%0A%0A  
+  List%3CMessage%3E messages = new ArrayList%3C%3E();%0A
     for (Ent
@@ -2663,26 +2663,24 @@
 ()) %7B%0A      
-  
 messages.add
@@ -2706,139 +2706,8 @@
 ));%0A
-      %7D%0A%0A      session.setAttribute(taskId, messages);%0A    %7D else %7B%0A      messages = (List%3CMessage%3E) session.getAttribute(taskId);%0A
     
@@ -4065,465 +4065,8 @@
 );%0A%0A
-    // Update the attribute stored in session%0A    HttpSession session = request.getSession();%0A    if (session.getAttribute(taskId) == null) %7B%0A      System.err.println(%22Illegal state of sending a message%22);%0A    %7D else %7B%0A      List%3CMessage%3E messages = (List%3CMessage%3E) session.getAttribute(taskId);%0A      messages.add(new Message(msgEntity));%0A      session.setAttribute(taskId, messages);%0A%0A      // After updating the session, store the message in datastore%0A  
     
@@ -4091,23 +4091,16 @@
 ntity);%0A
-    %7D%0A%0A
     resp

Revert the session implementation and change the wording of task id