package com.telephoners.krakyournet.ctf.resources;

import com.telephoners.krakyournet.ctf.beans.Flag;
import com.telephoners.krakyournet.ctf.beans.Solution;
import com.telephoners.krakyournet.ctf.beans.Team;
import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.beans.tasks.Task;
import com.telephoners.krakyournet.ctf.core.HashValidator;
import com.telephoners.krakyournet.ctf.repositories.SolutionsRepository;
import com.telephoners.krakyournet.ctf.repositories.TasksRepository;
import com.telephoners.krakyournet.ctf.repositories.TeamsRepository;
import io.dropwizard.auth.Auth;
import javafx.util.Pair;

import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Singleton
@Path(value = "/solutions")
@Produces(MediaType.APPLICATION_JSON)
public class SolutionsResource
{
    private TeamsRepository teamsRepository;
    private SolutionsRepository solutionsRepository;
    private TasksRepository tasksRepository;

    @Inject
    public SolutionsResource(SolutionsRepository solutionsRepository, TasksRepository tasksRepository,
                             TeamsRepository teamsRepository)
    {
        this.solutionsRepository = solutionsRepository;
        this.teamsRepository = teamsRepository;
        this.tasksRepository = tasksRepository;
    }

    @POST
    @Path("/{task_level}")
    public Response submitSolution(@Auth User user,
                                   @PathParam("task_level") int taskLevel,
                                   String hash) throws Exception
    {
        Pair<Task, Flag> taskFlagPair = tasksRepository.getTaskFlagPairByHashValue(user, hash, taskLevel);
        if (taskFlagPair != null) {
            if(solutionsRepository.submitSolution(new Solution(teamsRepository.getTeamByUser(user), taskFlagPair.getKey(), taskFlagPair.getValue(), hash))) {
                return Response.ok().build();
            }
        }
        return Response.status(Response.Status.NOT_ACCEPTABLE).build();
    }

    @GET
    @Path("/completed")
    public List<Integer> getTeamCompletedTasks(@Auth User user)
    {
        return solutionsRepository.getCompletedTasks(teamsRepository.getTeamByUser(user));
    }

    @GET
    @Path("/completed/all")
    public Map<String, List<Integer>> getAllTeamsCompletetdTasks(@Auth User user)
    {
        return teamsRepository.getAll()
                .stream()
                .collect(Collectors.toMap(
                        Team::getName,
                        team -> solutionsRepository.getCompletedTasks(team)
                ));
    }

    @GET
    @Path("/my")
    public Map<Integer, List<String>> getTeamSolutions(@Auth User user)
    {
        Team team = teamsRepository.getTeamByUser(user);
        return solutionsRepository.getTeamSolutions(team);
    }

    @GET
    @Path("/all")
    public Map<String, Map<Integer, List<String>>> getTeamsSolutions()
    {
        return teamsRepository.getAll()
                .stream()
                .collect(Collectors.toMap(
                        Team::getName,
                        team -> solutionsRepository.getTeamSolutions(team)
                ));
    }

}
