package com.google.sps.servlets;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceConfig;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.EmbeddedEntity;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseAuthException;
import com.google.firebase.auth.FirebaseToken;
import com.google.firebase.auth.UserRecord;
import com.google.gson.Gson;
import com.google.sps.firebase.FirebaseAppManager;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/get-workspace")
public class GetWorkspace extends HttpServlet {
  private FirebaseAuth authInstance;
  private DatastoreService datastore;
  private Gson gson;
  private static final String WORKSPACE = "/workspace/?workspaceID=";

  @Override
  public void init(ServletConfig config) throws ServletException {
    try {
      authInstance = FirebaseAuth.getInstance(FirebaseAppManager.getApp());
      gson = new Gson();
    } catch (IOException e) {
      throw new ServletException(e);
    }
  }

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    datastore = DatastoreServiceFactory.getDatastoreService();
    System.setProperty(
        DatastoreServiceConfig.DATASTORE_EMPTY_LIST_SUPPORT, Boolean.TRUE.toString());

    try {
      // Retrive class entity
      String classCode = request.getParameter("classCode").trim();
      Key classKey = KeyFactory.stringToKey(classCode);
      Entity classEntity = datastore.get(classKey);

      String studentID;
      if (request.getParameter("studentToken") == null) {
        // Get studentID from studentEmail
        String studentEmail = request.getParameter("studentEmail");
        UserRecord userRecord = authInstance.getUserByEmail(studentEmail);
        studentID = userRecord.getUid();
      } else {
        // Get studentID from studentToken
        String studentToken = request.getParameter("studentToken");
        FirebaseToken decodedToken = authInstance.verifyIdToken(studentToken);
        studentID = decodedToken.getUid();
      }

      EmbeddedEntity beingHelped = (EmbeddedEntity) classEntity.getProperty("beingHelped");
      EmbeddedEntity queueInfo = (EmbeddedEntity) beingHelped.getProperty(studentID);

      // Get workspace id
      String workspaceID = (String) queueInfo.getProperty("workspaceID");

      // Build workspace link
      String workspaceLink = WORKSPACE + workspaceID;

      response.setContentType("application/json;");
      response.getWriter().print(gson.toJson(workspaceLink));

    } catch (EntityNotFoundException e) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
    } catch (IllegalArgumentException e) {
      response.sendError(HttpServletResponse.SC_BAD_REQUEST);
    } catch (FirebaseAuthException e) {
      response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
  }
}

@@ -788,32 +788,82 @@
 io.IOException;%0A
+import java.util.List;%0Aimport java.util.Optional;%0A
 import javax.ser
@@ -2679,16 +2679,498 @@
      %7D%0A%0A
+      List%3CEmbeddedEntity%3E queue = (List%3CEmbeddedEntity%3E) classEntity.getProperty(%22studentQueue%22);%0A%0A      Optional%3CEmbeddedEntity%3E studentEntity =%0A          queue.stream().filter(elem -%3E elem.hasProperty(studentID)).findFirst();%0A%0A      String workspaceID;%0A      if (studentEntity.isPresent()) %7B%0A        workspaceID =%0A            (String)%0A                ((EmbeddedEntity) studentEntity.get().getProperty(studentID))%0A                    .getProperty(%22workspaceID%22);%0A      %7D else %7B%0A  
       Em
@@ -3249,24 +3249,26 @@
 ngHelped%22);%0A
+  
       Embedd
@@ -3338,24 +3338,26 @@
 tudentID);%0A%0A
+  
       // Get
@@ -3372,30 +3372,25 @@
 ce id%0A      
-String
+ 
  workspaceID
@@ -3438,16 +3438,24 @@
 aceID%22);
+%0A      %7D
 %0A%0A      

Check the student queue first to see if the user is still in the queue.