package com.google.sps.servlets;

import com.google.cloud.tasks.v2.AppEngineHttpRequest;
import com.google.cloud.tasks.v2.CloudTasksClient;
import com.google.cloud.tasks.v2.HttpMethod;
import com.google.cloud.tasks.v2.QueueName;
import com.google.cloud.tasks.v2.Task;
import com.google.protobuf.ByteString;
import com.google.sps.workspace.Workspace;
import com.google.sps.workspace.WorkspaceFactory;
import java.io.IOException;
import java.nio.charset.Charset;
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("/workspace/queueDownload")
public class QueueDownload extends HttpServlet {
  WorkspaceFactory workspaceFactory = WorkspaceFactory.getInstance();

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {
    Workspace w = workspaceFactory.fromWorkspaceID(req.getParameter("workspaceID"));

    String downloadID = w.newDownloadID();

    try (CloudTasksClient client = CloudTasksClient.create()) {
      String projectId = System.getenv("GOOGLE_CLOUD_PROJECT");
      String queueName = System.getenv("DOWNLOAD_QUEUE_ID");
      String location = System.getenv("LOCATION_ID");

      String queuePath = QueueName.of(projectId, location, queueName).toString();

      Task.Builder taskBuilder =
          Task.newBuilder()
              .setAppEngineHttpRequest(
                  AppEngineHttpRequest.newBuilder()
                      .setBody(
                          ByteString.copyFrom(
                              String.join(",", w.getWorkspaceID(), downloadID),
                              Charset.defaultCharset()))
                      .setRelativeUri("/tasks/prepareDownload")
                      .setHttpMethod(HttpMethod.POST)
                      .build());

      client.createTask(queuePath, taskBuilder.build());

      resp.getWriter().print(downloadID);
    }
  }
}

@@ -261,16 +261,72 @@
 2.Task;%0A
+import com.google.common.annotations.VisibleForTesting;%0A
 import c
@@ -892,154 +892,107 @@
 %0A%0A  
-@Override%0A  protected void doGet(HttpServletRequest req, HttpServletResponse resp)%0A      throws ServletException, IOException %7B%0A    Workspace w = 
+public QueueDownload() %7B%7D%0A%0A  protected QueueDownload(WorkspaceFactory workspaceFactory) %7B%0A    this.
 work
@@ -1007,22 +1007,20 @@
 tory
-.fromW
+ = w
 orkspace
 ID(r
@@ -1019,99 +1019,55 @@
 pace
-ID(req.getParameter(%22workspaceID%22))
+Factory
 ;%0A
-%0A
   
-  String downloadID = w.newDownloadID();%0A%0A    try (
+%7D%0A%0A  @VisibleForTesting%0A  protected 
 Clou
@@ -1083,59 +1083,124 @@
 ent 
-c
+getC
 lient
- = CloudTasksClient.create()) %7B%0A     
+() throws IOException %7B%0A    return CloudTasksClient.create();%0A  %7D%0A%0A  @VisibleForTesting%0A  protected
  String 
 proj
@@ -1199,19 +1199,35 @@
 ing 
-p
+getP
 rojectI
-d =
+D() %7B%0A    return
  Sys
@@ -1264,27 +1264,59 @@
 CT%22);%0A  
-   
+%7D%0A%0A  @VisibleForTesting%0A  protected
  String 
 queueNam
@@ -1307,25 +1307,28 @@
  String 
-q
+getQ
 ueueName
  = Syste
@@ -1319,18 +1319,31 @@
 ueueName
- =
+() %7B%0A    return
  System.
@@ -1373,27 +1373,59 @@
 ID%22);%0A  
-   
+%7D%0A%0A  @VisibleForTesting%0A  protected
  String 
 location
@@ -1420,18 +1420,34 @@
 ing 
-l
+getL
 ocation
- =
+() %7B%0A    return
  Sys
@@ -1473,16 +1473,330 @@
 N_ID%22);%0A
+  %7D%0A%0A  @Override%0A  protected void doGet(HttpServletRequest req, HttpServletResponse resp)%0A      throws ServletException, IOException %7B%0A    Workspace w = workspaceFactory.fromWorkspaceID(req.getParameter(%22workspaceID%22));%0A%0A    String downloadID = w.newDownloadID();%0A%0A    try (CloudTasksClient client = getClient()) %7B
 %0A      S
@@ -1830,38 +1830,51 @@
 .of(
-p
+getP
 rojectI
-d, location, q
+D(), getLocation(), getQ
 ueueName
 ).to
@@ -1869,16 +1869,18 @@
 ueueName
+()
 ).toStri

Refactor for testability.