package com.telephoners.krakyournet.ctf.resources;

import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.beans.tasks.Task;
import com.telephoners.krakyournet.ctf.beans.tasks.TaskRequestContext;
import com.telephoners.krakyournet.ctf.beans.tasks.TaskRequestContextBuilder;
import com.telephoners.krakyournet.ctf.beans.tasks.TaskResponse;
import com.telephoners.krakyournet.ctf.repositories.TasksRepository;
import io.dropwizard.auth.Auth;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.io.IOException;

@Singleton
@Path(value = "/task")
public class TaskResource
{
    private final TasksRepository tasksRepository;
    private final TaskRequestContextBuilder taskRequestContextBuilder;

    @Inject
    public TaskResource(TasksRepository tasksRepository, TaskRequestContextBuilder taskRequestContextBuilder)
    {
        this.tasksRepository = tasksRepository;
        this.taskRequestContextBuilder = taskRequestContextBuilder;
    }

    private Response buildResponse(TaskResponse taskResponse)
    {
        Response.ResponseBuilder responseBuilder = Response.ok();
        responseBuilder.entity(taskResponse.getText());
        taskResponse.getHeaders()
                .entrySet()
                .stream()
                .forEach(headerEntry -> {
                    responseBuilder.header(headerEntry.getKey(), headerEntry.getValue());
                });
        return responseBuilder.build();
    }

    private Response handleRequest(User user,
                                   int taskLevel,
                                   String path,
                                   ContainerRequestContext containerRequestContext) throws IOException
    {
        Task task = tasksRepository.getByLevel(taskLevel);
        TaskRequestContext taskRequestContext = taskRequestContextBuilder.from(user, path, containerRequestContext);
        return buildResponse(task.getTaskResponse(taskRequestContext));
    }

    @Path("{task_level}/{path: .*}")
    @GET
    public Response getTaskGet(@Auth User user,
                               final @PathParam("task_level") int taskLevel,
                               final @PathParam("path") String path,
                               @Context ContainerRequestContext containerRequestContext) throws IOException
    {
        return handleRequest(user, taskLevel, path, containerRequestContext);
    }


    @Path("{task_level}/{path: .*}")
    @POST
    public Response getTaskPost(@Auth User user,
                                final @PathParam("task_level") int taskLevel,
                                final @PathParam("path") String path,
                                @Context ContainerRequestContext containerRequestContext) throws IOException
    {
        return handleRequest(user, taskLevel, path, containerRequestContext);
    }
}
