package com.adeptik.gateway.client;

import com.adeptik.gateway.client.exceptions.RequestException;
import com.adeptik.gateway.client.model.AccessServiceState;
import com.adeptik.gateway.client.utils.StreamHandler;
import com.adeptik.gateway.contracts.Routes;
import com.adeptik.gateway.contracts.dto.agents.AgentJobDTO;
import com.adeptik.gateway.contracts.dto.agents.PostAgentStateInputDTO;
import com.adeptik.gateway.contracts.dto.agents.PutAlgorithmStateDTO;
import com.adeptik.gateway.contracts.dto.security.TokenDTO;
import okhttp3.Request;
import okhttp3.Response;

import java.io.IOException;
import java.net.URL;

@SuppressWarnings("unused")
public class Agent extends AccessRefreshGatewayClient {

    Agent(URL gatewayUrl, AccessServiceState state) {

        super(
                gatewayUrl,
                state,
                Routes.AgentBaseUrl + "/token",
                "x-agent",
                "x-agent-service");
    }

    public AgentJobDTO postState(PostAgentStateInputDTO postAgentStateInputDTO)
            throws IOException, RequestException {

        Request request = createAuthorizedRequestBuilder(Routes.AgentBaseUrl + "/state")
                .post(createJsonRequestBody(postAgentStateInputDTO, PostAgentStateInputDTO.class))
                .build();
        try (Response response = createHttpClient().newCall(request).execute()) {

            return readJsonResponse(response, AgentJobDTO.class);
        }
    }

    public TokenDTO acceptAssignment()
            throws IOException, RequestException {

        Request request = createAuthorizedRequestBuilder(Routes.AgentBaseUrl + "/assignment/accept")
                .patch(createEmptyRequestBody())
                .build();
        try (Response response = createHttpClient().newCall(request).execute()) {

            return readJsonResponse(response, TokenDTO.class);
        }
    }

    public void getAlgorithmDefinition(long algorithmId, String[] runtimes, StreamHandler resultHandler)
            throws IOException, RequestException {

        if (runtimes == null)
            throw new IllegalArgumentException("runtimes not specified");
        if (resultHandler == null)
            throw new NullPointerException("resultHandler is null");

        Request request = createAuthorizedRequestBuilder(
                Routes.AlgorithmBaseUrl + "/" + algorithmId + "/definition?runtimes=" + String.join(",", runtimes))
                .get()
                .build();
        try (Response response = createHttpClient().newCall(request).execute()) {

            readFileResponse(response, resultHandler);
        }
    }

    public void getProblemDefinition(long problemId, StreamHandler resultHandler)
            throws IOException, RequestException {

        if (resultHandler == null)
            throw new NullPointerException("resultHandler is null");

        Request request = createAuthorizedRequestBuilder(Routes.ProblemBaseUrl + "/" + problemId + "/definition")
                .get()
                .build();
        try (Response response = createHttpClient().newCall(request).execute()) {

            readFileResponse(response, resultHandler);
        }
    }

    public void putAlgorithm(long algorithmId, PutAlgorithmStateDTO putAlgorithmStateDTO)
            throws IOException, RequestException {

        Request request = createAuthorizedRequestBuilder(Routes.AgentBaseUrl + "/algorithm/" + algorithmId)
                .put(createJsonRequestBody(putAlgorithmStateDTO, PutAlgorithmStateDTO.class))
                .build();

        try (Response response = createHttpClient().newCall(request).execute()) {

            throwOnUnsuccessfulResponse(response);
        }
    }
}

@@ -512,24 +512,151 @@
 y.TokenDTO;%0A
+import com.google.common.base.Function;%0Aimport com.google.common.base.Joiner;%0Aimport com.google.common.collect.FluentIterable;%0A
 import okhtt
@@ -2367,32 +2367,466 @@
 ler is null%22);%0A%0A
+        //noinspection Guava,Convert2Lambda%0A        String runtimesQuery = Joiner.on(%22&%22)%0A                .join(FluentIterable.of(runtimes)%0A                        .transform(new Function%3CString, String%3E() %7B%0A%0A                            @Override%0A                            public String apply(String runtime) %7B%0A                                return %22runtimes=%22 + runtime;%0A                            %7D%0A                        %7D));%0A
         Request 
@@ -2946,37 +2946,11 @@
 ion?
-runtimes=%22 + String.join(%22,%22,
+%22 +
  run
@@ -2954,17 +2954,21 @@
 runtimes
-)
+Query
 )%0A      

fix getAlgorithmDefinition query format