package com.iqser.red.service.peristence.v1.server.integration.tests;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.iqser.red.service.peristence.v1.server.integration.client.DossierClient;
import com.iqser.red.service.peristence.v1.server.integration.client.WatermarkClient;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTesterAndProvider;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.WatermarkModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.WatermarkOrientation;

import feign.FeignException;

public class WatermarkTest extends AbstractPersistenceServerServiceTest {

    @Autowired
    private DossierTemplateTesterAndProvider dossierTemplateTesterAndProvider;

    @Autowired
    private DossierTesterAndProvider dossierTesterAndProvider;

    @Autowired
    private WatermarkClient watermarkClient;

    @Autowired
    private DossierClient dossierClient;


    @Test
    public void testWatermark() {

        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
        try {
            watermarkClient.getWatermark(13L);
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(404);
        }

        var watermark = new WatermarkModel();
        watermark.setName("watermark name");
        watermark.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor("#dddddd");
        watermark.setOpacity(20);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setDossierTemplateId(dossierTemplate.getId());
        watermark.setCreatedBy("user");

        var saved = watermarkClient.saveWatermark(watermark);
        var loadedWatermark = watermarkClient.getWatermark(saved.getId());
        assertThat(loadedWatermark).isEqualTo(saved);
        assertThat(saved.getDateAdded()).isNotNull();
        // try to save the same watermark without id
        try {
            watermarkClient.saveWatermark(watermark);
        } catch (FeignException e) {
            assertThat(e.status()).isEqualTo(409);
        }

        // try to save the same watermark with id
        try {
            watermarkClient.saveWatermark(saved);
        } catch (FeignException e) {
            assertThat(e.status()).isEqualTo(409);
        }

        // update current watermark
        saved.setFontSize(14);
        saved.setEnabled(true);
        saved.setDossierTemplateId(null);
        var updated = watermarkClient.saveWatermark(saved);
        assertThat(updated.getDossierTemplateId()).isEqualTo(dossierTemplate.getId());
        assertThat(updated.getDateModified()).isNotNull();
        assertThat(updated.isEnabled()).isTrue();

        assertThat(watermarkClient.isWatermarkUsed(updated.getId())).isEqualTo(JSONPrimitive.of(false));

        var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);

        // update dossier with watermark config
        var cru = new DossierRequest();

        BeanUtils.copyProperties(dossier, cru);
        cru.setDossierId(dossier.getId());
        cru.setWatermarkId(updated.getId());

        var updatedDossier = dossierClient.createDossierOrUpdateDossier(cru).getBody();
        assertThat(updatedDossier.getWatermarkId()).isEqualTo(updated.getId());

        assertThat(watermarkClient.isWatermarkUsed(updated.getId())).isEqualTo(JSONPrimitive.of(true));

        // update current watermark with new dossier template id
        updated.setDossierTemplateId("dossierTemplate2");
        try {
            watermarkClient.saveWatermark(updated);
        } catch (FeignException e) {
            assertThat(e.status()).isEqualTo(409);
        }

        var watermarkList = watermarkClient.getWatermarksForDossierTemplateId(dossierTemplate.getId());
        assertThat(watermarkList.size()).isEqualTo(1);

        // create new watermark with same name:
        var watermark2 = new WatermarkModel();
        watermark2.setName("watermark name");
        watermark2.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark2.setDossierTemplateId(dossierTemplate.getId());

        try {
            watermarkClient.saveWatermark(watermark2);
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(409);
        }

    }


    @Test
    public void testDeleteWatermark() {

        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();

        var watermark = new WatermarkModel();
        watermark.setName("watermark name");
        watermark.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor("#dddddd");
        watermark.setOpacity(20);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setDossierTemplateId(dossierTemplate.getId());

        var saved = watermarkClient.saveWatermark(watermark);
        var loadedWatermark = watermarkClient.getWatermark(saved.getId());
        assertThat(loadedWatermark).isEqualTo(saved);

        // Delete first time
        watermarkClient.deleteWatermark(saved.getId());

        try {
            watermarkClient.getWatermark(saved.getId());
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(404);
        }

        // try to delete a not existing watermark
        try {
            watermarkClient.deleteWatermark(saved.getId());
        } catch (FeignException e) {
            assertThat(e.status()).isEqualTo(404);
        }

    }


    @Test
    public void testCreateWatermark() {

        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();

        var watermark = new WatermarkModel();
        watermark.setName("watermark name");
        watermark.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor("#dddddd");
        watermark.setOpacity(20);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setDossierTemplateId(dossierTemplate.getId());

        var saved = watermarkClient.saveWatermark(watermark);
        var loadedWatermark = watermarkClient.getWatermark(saved.getId());
        assertThat(loadedWatermark).isEqualTo(saved);

        // try to save the same watermark
        try {
            watermarkClient.saveWatermark(watermark);
        } catch (FeignException e) {
            assertThat(e.status()).isEqualTo(409);
        }

        var watermark2 = new WatermarkModel();
        watermark.setName("watermark name2");
        watermark.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark.setFontSize(12);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setDossierTemplateId(dossierTemplate.getId());

        var saved2 = watermarkClient.saveWatermark(watermark);
        var loadedWatermark2 = watermarkClient.getWatermark(saved.getId());
    }

    @Test
    public void testCreateWatermarkWithInvalidHexColor() {

        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();

        var color = "000000";
        var watermark = new WatermarkModel();
        watermark.setName("watermark name");
        watermark.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor(color);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setDossierTemplateId(dossierTemplate.getId());

        Exception exception = Assertions.assertThrows(FeignException.BadRequest.class, () -> {
            watermarkClient.saveWatermark(watermark);
        });

        String expectedMessage = "The specified color: " + color + " is malformed.";
        String actualMessage = exception.getMessage();

        assertThat(actualMessage).contains(expectedMessage);

        watermark.setHexColor(null);
        var saved2 = watermarkClient.saveWatermark(watermark);

        assertThat(saved2.getHexColor()).isEqualTo("#000000");
    }


    @Test
    public void testCreateWatermarkWithDifferentOpacities() {

        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
        // create watermark with no opacity set
        var color = "#000000";
        var watermark = new WatermarkModel();
        watermark.setName("watermark name");
        watermark.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor(color);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setDossierTemplateId(dossierTemplate.getId());
        assertThat(watermark.getOpacity()).isEqualTo(0);

        var saved2 = watermarkClient.saveWatermark(watermark);

        assertThat(saved2.getOpacity()).isEqualTo(0);

        // create watermark with invalid opacity
        var watermark2 = new WatermarkModel();
        watermark2.setName("watermark name2");
        watermark2.setText("Minions ipsum chasy para tu la bodaaa bananaaaa hana dul sae. Chasy hana dul sae pepete hana dul sae belloo! Tatata bala tu ti aamoo! Jeje.");
        watermark2.setFontSize(14);
        watermark2.setFontType("font");
        watermark2.setHexColor(color);
        watermark2.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark2.setDossierTemplateId(dossierTemplate.getId());
        watermark2.setOpacity(-1);

        saved2 = watermarkClient.saveWatermark(watermark2);

        assertThat(saved2.getOpacity()).isEqualTo(30);
    }

    @Test
    public void testWatermarkTextWithJapaneseText() {

        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
        var watermarkText = "本資料に記載された情報に係る権利及び内容の責任はシンジェンタジャパン株式会社にある。";

        var watermark = new WatermarkModel();
        watermark.setName("japanese");
        watermark.setEnabled(true);
        watermark.setDossierTemplateId(dossierTemplate.getId());
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor("#dddddd");
        watermark.setOpacity(20);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setText(watermarkText);

        var saved = watermarkClient.saveWatermark(watermark);
        var loadedWatermarked = watermarkClient.getWatermark(saved.getId());

        assertThat(loadedWatermarked).isEqualTo(saved);
        assertThat(loadedWatermarked.getText()).isEqualTo(watermarkText);
    }


    @Test
    public void testWatermarkTextWithCorrectText() {

        // Arrange
        var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
        var watermarkText = "We love ASCII!\n\nThis text contains only ASCII chars and newlines\r\r\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";

        var watermark = new WatermarkModel();
        watermark.setName("name");
        watermark.setEnabled(true);
        watermark.setDossierTemplateId(dossierTemplate.getId());
        watermark.setFontSize(12);
        watermark.setFontType("font");
        watermark.setHexColor("#dddddd");
        watermark.setOpacity(20);
        watermark.setOrientation(WatermarkOrientation.DIAGONAL);
        watermark.setText(watermarkText);

        // Act
        var saved = watermarkClient.saveWatermark(watermark);
        var loadedWatermarked = watermarkClient.getWatermark(saved.getId());

        // Assert
        assertThat(loadedWatermarked).isEqualTo(saved);
        assertThat(loadedWatermarked.getText()).isEqualTo(watermarkText);
    }

}
