package io.reflectoring.coderadar.rest.query;

import static io.reflectoring.coderadar.rest.JsonHelper.fromJson;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;

import com.fasterxml.jackson.core.type.TypeReference;
import io.reflectoring.coderadar.projectadministration.port.driver.project.create.CreateProjectCommand;
import io.reflectoring.coderadar.query.domain.CommitLog;
import io.reflectoring.coderadar.rest.ControllerTestTemplate;
import io.reflectoring.coderadar.rest.domain.IdResponse;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;

public class GetCommitLogControllerTest extends ControllerTestTemplate {

  private Long projectId;

  @BeforeEach
  void setUp() throws Exception {
    URL testRepoURL = this.getClass().getClassLoader().getResource("test-repository");
    CreateProjectCommand command1 =
        new CreateProjectCommand(
            "test-project", "username", "password", testRepoURL.toString(), false, null, null);
    MvcResult result =
        mvc()
            .perform(
                post("/projects").contentType(MediaType.APPLICATION_JSON).content(toJson(command1)))
            .andReturn();

    projectId = fromJson(result.getResponse().getContentAsString(), IdResponse.class).getId();
  }

  @Test
  void returnsCommitLog() throws Exception {
    MvcResult result =
        mvc()
            .perform(
                get("/projects/" + projectId + "/commitLog")
                    .contentType(MediaType.APPLICATION_JSON))
            .andDo(
                document(
                    "commit/log",
                    responseFields(
                        fieldWithPath("[]")
                            .description(
                                "Array of the commits in this project in a git log similar format."),
                        fieldWithPath("[].refs")
                            .description("Array of strings with the refs pointing to the commit"),
                        fieldWithPath("[].parents")
                            .description("Array of strings with the parents of the commit"),
                        fieldWithPath("[].hash").description("The hash of the commit."),
                        fieldWithPath("[].author.name").description("The name of the author"),
                        fieldWithPath("[].author.email").description("The email of the author"),
                        fieldWithPath("[].author.timestamp")
                            .description("The timestamp of the commit"),
                        fieldWithPath("[].author")
                            .description("Object containing author information about the commit."),
                        fieldWithPath("[].subject")
                            .description(
                                "The comment of this commit truncated to the first 100 characters."),
                        fieldWithPath("[].analyzed")
                            .description("Whether this commit is already analyzed or not."))))
            .andReturn();

    List<CommitLog> commits =
        fromJson(
            new TypeReference<List<CommitLog>>() {}, result.getResponse().getContentAsString());

    Assertions.assertEquals(15, commits.size());
    CommitLog last = commits.get(0);
    Assertions.assertEquals("e9f7ff6fdd8c0863fdb5b24c9ed35a3651e20382", last.getHash());
    Assertions.assertEquals("modify testModule1/NewRandomFile.java", last.getSubject());
    Assertions.assertEquals(Collections.singletonList("master"), last.getRefs());
    Assertions.assertArrayEquals(
        new String[] {"d3272b3793bc4b2bc36a1a3a7c8293fcf8fe27df"}, last.getParents());
    Assertions.assertEquals("Kilian.Krause@adesso.de", last.getAuthor().getEmail());
    Assertions.assertEquals("Krause", last.getAuthor().getName());
    Assertions.assertEquals(1584013941000L, last.getAuthor().getTimestamp());

    CommitLog secondToLast = commits.get(1);
    Assertions.assertEquals("fcd9a0e7c34086fdb0aedc82497f8ddfa142e961", secondToLast.getHash());
    Assertions.assertEquals("added TestFile.java", secondToLast.getSubject());
    Assertions.assertEquals(Collections.singletonList("testBranch2"), secondToLast.getRefs());
    Assertions.assertArrayEquals(
        new String[] {"d3272b3793bc4b2bc36a1a3a7c8293fcf8fe27df"}, secondToLast.getParents());
    Assertions.assertEquals("Maksim.Atanasov@adesso.de", secondToLast.getAuthor().getEmail());
    Assertions.assertEquals("Atanasov", secondToLast.getAuthor().getName());
    Assertions.assertEquals(1582619029000L, secondToLast.getAuthor().getTimestamp());
  }
}

@@ -2449,32 +2449,129 @@
 o the commit%22),%0A
+                            fieldWithPath(%22%5B%5D.hash%22).description(%22The hash of the commit.%22),%0A    
                 
@@ -2715,32 +2715,36 @@
                 
+    
 fieldWithPath(%22%5B
@@ -2749,39 +2749,109 @@
 %22%5B%5D.
-hash%22).description(%22The hash of
+author%22)%0A                                    .description(%22Object containing author information about
  the
@@ -3192,159 +3192,8 @@
 %22),%0A
-                        fieldWithPath(%22%5B%5D.author%22)%0A                            .description(%22Object containing author information about the commit.%22),%0A
     

swap parents and hash and document author object before documenting the author fields