package com.telephoners.krakyournet.ctf.beans.tasks;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.telephoners.krakyournet.ctf.beans.User;
import com.telephoners.krakyournet.ctf.core.ApplicationConfiguration;
import com.telephoners.krakyournet.ctf.helpers.StreamUtils;
import org.eclipse.jetty.http.HttpMethod;
import org.glassfish.jersey.server.ContainerRequest;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.MultivaluedMap;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Singleton
public class TaskRequestContextBuilder
{

    private ApplicationConfiguration applicationConfiguration;

    @Inject
    public TaskRequestContextBuilder(ApplicationConfiguration applicationConfiguration)
    {
        this.applicationConfiguration = applicationConfiguration;
    }

    private Map<String, String> extractProxiedHeaders(MultivaluedMap<String, String> headers)
    {
        Set<String> proxiedHeaders = applicationConfiguration.getProxiedHeaders();
        return headers.entrySet()
                .stream()
                .filter(header -> proxiedHeaders.contains(header.getKey()))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        entry -> entry.getValue().get(0) //todo: check
                ));
    }

    public TaskRequestContext from(User user, String path, ContainerRequestContext containerRequestContext) throws IOException
    {
        String fullPath = path;
        TaskRequestContext taskRequestContext = new TaskRequestContext();
        if (user != null) {
            taskRequestContext.withUser(user);
        }
        if (path != null) {
            taskRequestContext.withPath(path);
            String httpMethod = containerRequestContext.getMethod();
            String query = ((ContainerRequest) containerRequestContext).getRequestUri().getQuery();

            if (query != null) {
                fullPath += "?" + query;
            }
            taskRequestContext.withPath(fullPath);

            if(httpMethod.equals("GET")) {
                taskRequestContext.withHttpMethod(HttpMethod.GET);
            }

            else if (httpMethod.equals("POST")) {
                taskRequestContext.withHttpMethod(HttpMethod.POST);
                String body = StreamUtils.readStream(containerRequestContext.getEntityStream());
                taskRequestContext.withBody(body);
            }
            else {
                throw new IllegalStateException("Invalid http method");
            }

            Map<String, String> proxiedHeaders = extractProxiedHeaders(containerRequestContext.getHeaders());
            taskRequestContext.withHeaders(proxiedHeaders);
        }
        return taskRequestContext;
    }
}
