package mtsar.resources;

import mtsar.api.Answer;
import mtsar.api.Process;
import mtsar.api.TaskAllocation;
import mtsar.api.Worker;
import mtsar.api.sql.AnswerDAO;
import mtsar.api.sql.TaskDAO;
import mtsar.api.sql.WorkerDAO;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

@Produces(MediaType.APPLICATION_JSON)
public class WorkerResource {
    protected final mtsar.api.Process process;
    protected final TaskDAO taskDAO;
    protected final WorkerDAO workerDAO;
    protected final AnswerDAO answerDAO;

    public WorkerResource(Process process, TaskDAO taskDAO, WorkerDAO workerDAO, AnswerDAO answerDAO) {
        this.process = process;
        this.taskDAO = taskDAO;
        this.workerDAO = workerDAO;
        this.answerDAO = answerDAO;
    }

    @GET
    public List<Worker> getWorkers() {
        return workerDAO.listForProcess(process.getId());
    }

    @POST
    public Worker postWorker(@FormParam("external_id") String externalId) {
        Worker w = Worker.builder().
                setExternalId(externalId).
                setProcess(process.getId()).
                setDateTime(Timestamp.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant())).
                build();
        int workerId = workerDAO.insert(w);
        return workerDAO.find(workerId, process.getId());
    }

    @GET
    @Path("{worker}")
    public Worker getWorker(@PathParam("worker") Integer id) {
        return fetchWorker(id);
    }

    @GET
    @Path("external")
    public Worker getWorkerByExternalId(@QueryParam("externalId") String externalId) {
        final Worker worker = workerDAO.findByExternalId(externalId, process.getId());
        if (worker == null) throw new WebApplicationException(Response.Status.NOT_FOUND);
        return worker;
    }

    @GET
    @Path("{worker}/task")
    public TaskAllocation getWorkerTask(@PathParam("worker") Integer id) {
        final Worker w = fetchWorker(id);
        return process.getTaskAllocator().allocate(w).get();
    }

    @GET
    @Path("{worker}/answers")
    public List<Answer> getWorkerAnswers(@PathParam("worker") Integer id) {
        final Worker w = fetchWorker(id);
        return answerDAO.listForWorker(w.getId(), process.getId());
    }

    @DELETE
    @Path("{worker}")
    public Worker deleteWorker(@PathParam("worker") Integer id) {
        final Worker w = fetchWorker(id);
        throw new WebApplicationException(Response.Status.NOT_IMPLEMENTED);
    }

    private Worker fetchWorker(Integer id) {
        final Worker w = workerDAO.find(id, process.getId());
        if (w == null) {
            throw new WebApplicationException(Response.Status.NOT_FOUND);
        }
        return w;
    }
}

@@ -36,22 +36,17 @@
 sar.api.
-Answer
+*
 ;%0Aimport
@@ -69,66 +69,8 @@
 ss;%0A
-import mtsar.api.TaskAllocation;%0Aimport mtsar.api.Worker;%0A
 impo
@@ -357,16 +357,43 @@
 il.List;
+%0Aimport java.util.Optional;
 %0A%0A@Produ
@@ -2058,59 +2058,155 @@
     
-return process.getTaskAllocator().allocate(w).get()
+final Optional%3CTaskAllocation%3E allocation = process.getTaskAllocator().allocate(w);%0A        return allocation.isPresent() ? allocation.get() : null
 ;%0A  

Return 204 when task allocation is not present