package eu.nimble.core.infrastructure.identity.system;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.nimble.core.infrastructure.identity.IdentityServiceApplication;
import eu.nimble.core.infrastructure.identity.config.DefaultTestConfiguration;
import eu.nimble.core.infrastructure.identity.entity.UaaUser;
import eu.nimble.core.infrastructure.identity.entity.dto.*;
import eu.nimble.core.infrastructure.identity.repository.*;
import eu.nimble.service.model.ubl.commonaggregatecomponents.PersonType;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.kafka.test.rule.KafkaEmbedded;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import java.util.Collections;

import static eu.nimble.core.infrastructure.identity.TestUtils.JSON_DATE_FORMAT;
import static eu.nimble.core.infrastructure.identity.TestUtils.createCompanyRegistration;
import static eu.nimble.core.infrastructure.identity.config.NimbleConfigurationProperties.LanguageID.ENGLISH;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

/**
 * Created by Johannes Innerbichler on 09.08.18.
 */
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = IdentityServiceApplication.class)
@AutoConfigureMockMvc
@ActiveProfiles("test")
@FixMethodOrder
@Import(DefaultTestConfiguration.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
public class AdminControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private PartyRepository partyRepository;

    @Autowired
    private QualifyingPartyRepository qualifyingPartyRepository;

    @Autowired
    private PersonRepository personRepository;

    @Autowired
    private UaaUserRepository uaaUserRepository;

    @Autowired
    private DeliveryTermsRepository deliveryTermsRepository;

    @Autowired PaymentMeansRepository paymentMeansRepository;

    @Autowired
    private DocumentReferenceRepository documentReferenceRepository;

    @Autowired
    private ObjectMapper objectMapper;

    @ClassRule
    public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "topic");

    @Test
    public void testDeleteCompany() throws Exception {
        PersonType person = personRepository.save(new PersonType());
        uaaUserRepository.save(new UaaUser("testuser", person, "externalID"));
        CompanyRegistration companyRegistration = createCompanyRegistration("company_name", person);

        // GIVEN: existing company on platform
        Gson gson = new GsonBuilder().setDateFormat(JSON_DATE_FORMAT).create();
        String responseAsString = this.mockMvc.perform(post("/register/company").contentType(MediaType.APPLICATION_JSON)
                .header(HttpHeaders.AUTHORIZATION, "Bearer DUMMY_TOKEN")
                .content(gson.toJson(companyRegistration)))
                .andExpect(status().isOk())
                .andReturn().getResponse().getContentAsString();
        companyRegistration = objectMapper.readValue(responseAsString, CompanyRegistration.class);

        // check list of all parties whether it contains newly registered company
        this.mockMvc.perform(get("/parties/all?page=0"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.content.length()", is(1)))
                .andExpect(jsonPath("$.content[0].partyName[0].name.value", is(companyRegistration.getSettings().getDetails().getLegalName().get(ENGLISH))))
                .andExpect(jsonPath("$.content[0].partyIdentification[0].id", is(companyRegistration.getCompanyID().toString())));

        // check repositories
        assertEquals(1, this.partyRepository.count());
        assertEquals(1, this.qualifyingPartyRepository.count());
        assertEquals(1, this.personRepository.count());
        assertEquals(1, this.uaaUserRepository.count());
        assertEquals(1, this.deliveryTermsRepository.count());
        assertEquals(1, this.paymentMeansRepository.count());
        assertEquals(1, this.documentReferenceRepository.count());

        // WHEN: deleting company
        this.mockMvc.perform(delete("/admin/delete_company/" + companyRegistration.getCompanyID())
                .header(HttpHeaders.AUTHORIZATION, "Bearer DUMMY_TOKEN"))
                .andExpect(status().isOk());

        // THEN: company should be deleted
        this.mockMvc.perform(get("/parties/all"))
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.content.length()", is(1)));

        // check repositories
        assertEquals(1, this.partyRepository.count());
        assertEquals(1, this.personRepository.count());
    }
}

@@ -5103,24 +5103,26 @@
 .count());%0A%0A
+//
         // W
@@ -5135,32 +5135,34 @@
 eleting company%0A
+//
         this.moc
@@ -5240,24 +5240,26 @@
 ompanyID())%0A
+//
             
@@ -5316,24 +5316,26 @@
 MY_TOKEN%22))%0A
+//
             
@@ -5363,25 +5363,29 @@
 ().isOk());%0A
-%0A
+//%0A//
         // T
@@ -5415,16 +5415,18 @@
 deleted%0A
+//
         
@@ -5463,24 +5463,26 @@
 ties/all%22))%0A
+//
             
@@ -5493,32 +5493,34 @@
 .andDo(print())%0A
+//
                 
@@ -5539,32 +5539,34 @@
 tatus().isOk())%0A
+//
                 
@@ -5633,32 +5633,34 @@
 LICATION_JSON))%0A
+//
                 
@@ -5706,25 +5706,29 @@
 %22, is(1)));%0A
-%0A
+//%0A//
         // c
@@ -5737,32 +5737,34 @@
 ck repositories%0A
+//
         assertEq
@@ -5794,32 +5794,34 @@
 itory.count());%0A
+//
         assertEq

test fix.