/*
 * Copyright (C) 2024 Das Land Schleswig-Holstein vertreten durch den
 * Ministerpräsidenten des Landes Schleswig-Holstein
 * Staatskanzlei
 * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung
 *
 * Lizenziert unter der EUPL, Version 1.2 oder - sobald
 * diese von der Europäischen Kommission genehmigt wurden -
 * Folgeversionen der EUPL ("Lizenz");
 * Sie dürfen dieses Werk ausschließlich gemäß
 * dieser Lizenz nutzen.
 * Eine Kopie der Lizenz finden Sie hier:
 *
 * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
 *
 * Sofern nicht durch anwendbare Rechtsvorschriften
 * gefordert oder in schriftlicher Form vereinbart, wird
 * die unter der Lizenz verbreitete Software "so wie sie
 * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN -
 * ausdrücklich oder stillschweigend - verbreitet.
 * Die sprachspezifischen Genehmigungen und Beschränkungen
 * unter der Lizenz sind dem Lizenztext zu entnehmen.
 */
package de.ozgcloud.admin.setting;

import static org.assertj.core.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheit;
import de.ozgcloud.admin.organisationseinheit.OrganisationsEinheitTestFactory;
import de.ozgcloud.admin.setting.postfach.PostfachSettingBodyTestFactory;
import de.ozgcloud.common.test.DataITCase;
import lombok.SneakyThrows;

@DataITCase
@AutoConfigureMockMvc
@WithMockUser
class SettingEnvironmentITCase {

	@Autowired
	private MockMvc mockMvc;
	@Autowired
	private MongoOperations mongoOperations;

	@Test
	@SneakyThrows
	void shouldHaveHttpEndpoint() {
		var result = mockMvc.perform(get("/configserver/example/path"));

		result.andExpect(status().isOk());
	}

	@DisplayName("Get alfa settings")
	@Nested
	class TestGetAlfaSettings {

		@Nested
		class OnInitialStartup {

			@BeforeEach
			void fillDb() {
				fillDbWithInitialSettings();
			}

			@Test
			@SneakyThrows
			void shouldHandleEmptySetting() {
				var result = getAlfaSetting();

				assertThat(formatLineBreaks(result.andReturn().getResponse().getContentAsString())).isEqualTo(YamlTestFactory.createInitialYaml());
			}
		}

		@Nested
		class OnSettingsAvailable {

			@BeforeEach
			void fillDb() {
				fillDbWithPostfachSettings();
			}

			@Test
			@SneakyThrows
			void shouldReturnValuesForAlfa() {
				var result = getAlfaSetting();

				assertThat(formatLineBreaks(result.andReturn().getResponse().getContentAsString())).isEqualTo(YamlTestFactory.createAlfaYaml());
			}
		}

		private ResultActions getAlfaSetting() throws Exception {
			return mockMvc.perform(get("/configserver/Alfa-any.yaml")).andExpect(status().isOk());
		}
	}

	@Nested
	class TestGetVorgangManagerSettings {

		@Nested
		class OnInitialStartup {

			@BeforeEach
			void fillDb() {
				fillDbWithInitialSettings();
			}

			@Test
			@SneakyThrows
			void shouldHandleEmptySetting() {
				var result = getVorgangManagerSetting();

				assertThat(formatLineBreaks(result.andReturn().getResponse().getContentAsString())).isEqualTo(YamlTestFactory.createInitialYaml());
			}
		}

		@Nested
		class OnSettingsAvailable {

			@BeforeEach
			void fillDb() {
				fillDbWithPostfachSettings();
			}

			@Test
			@SneakyThrows
			void shouldReturnValuesForVorgangManager() {
				var result = getVorgangManagerSetting();

				assertThat(formatLineBreaks(result.andReturn().getResponse().getContentAsString()))
						.isEqualTo(YamlTestFactory.createVorgangManagerYaml());
			}
		}

		private ResultActions getVorgangManagerSetting() throws Exception {
			return mockMvc.perform(get("/configserver/OzgCloud_VorgangManager-profile.yaml")).andExpect(status().isOk());
		}
	}

	private String formatLineBreaks(String text) {
		return text.replaceAll("\\\\\\s+\\\\", "").replace("\\n", "\n");
	}

	private void fillDbWithInitialSettings() {
		var initialSetting = Setting.builder().name("Postfach").build();
		mongoOperations.dropCollection(Setting.class);
		mongoOperations.dropCollection(OrganisationsEinheit.class);
		mongoOperations.save(initialSetting);
	}

	private void fillDbWithPostfachSettings() {
		var postfachSettings = SettingTestFactory.createBuilder()
				.name("Postfach")
				.settingBody(PostfachSettingBodyTestFactory.create())
				.build();
		mongoOperations.dropCollection(Setting.class);
		mongoOperations.dropCollection(OrganisationsEinheit.class);
		mongoOperations.save(postfachSettings);
		mongoOperations.save(OrganisationsEinheitTestFactory.create());
	}
}