package ch.unisg.executorpool;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.BDDAssertions.*;

import ch.unisg.executorpool.adapter.common.formats.ExecutorJsonRepresentation;
import ch.unisg.executorpool.application.port.out.AddExecutorPort;
import ch.unisg.executorpool.domain.ExecutorPool;
import ch.unisg.executorpool.domain.ExecutorClass;
import ch.unisg.executorpool.domain.ExecutorClass.ExecutorTaskType;
import ch.unisg.executorpool.domain.ExecutorClass.ExecutorUri;


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AddNewExecutorToExecutorPoolSystemTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private AddExecutorPort addExecutorPort;

    @Test
    void AddNewExecutorToExecutorPool() throws JSONException {

        ExecutorTaskType executorTaskType  = new ExecutorTaskType("system-integration-test-type");
        ExecutorUri executorUri = new ExecutorUri(java.net.URI.create("example.org"));

        ResponseEntity response = whenAddNewExecutorToEmptyPool(executorTaskType, executorUri);

        JSONObject responseJson = new JSONObject(response.getBody().toString());
        String respExecutorUri = responseJson.getString("executorUri");
        String respExecutorTaskType = responseJson.getString("executorTaskType");

        then(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
        then(respExecutorUri).isEqualTo(executorUri.getValue().toString());
        then(respExecutorTaskType).isEqualTo(executorTaskType.getValue());
        then(ExecutorPool.getExecutorPool().getListOfExecutors().getValue()).hasSize(1);

    }

    private ResponseEntity whenAddNewExecutorToEmptyPool(ExecutorTaskType executorTaskType,
    ExecutorUri executorUri) throws JSONException {

        ExecutorPool.getExecutorPool().getListOfExecutors().getValue().clear();

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", ExecutorJsonRepresentation.EXECUTOR_MEDIA_TYPE);

        String jsonPayLoad = new JSONObject().put("executorTaskType", executorTaskType.getValue())
        .put("executorUri", executorUri.getValue()).toString();


        HttpEntity<String> request = new HttpEntity<>(jsonPayLoad,headers);

        return restTemplate.exchange("/executor-pool/AddExecutor", HttpMethod.POST, request, Object.class);

    }

}
