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

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

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;

import com.iqser.red.service.peristence.v1.server.integration.client.DigitalSignatureClient;
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DigitalSignatureKms;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DigitalSignatureViewModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.configuration.DigitalSignature;
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;

import feign.FeignException;
import lombok.SneakyThrows;

public class DigitalSignatureTest extends AbstractPersistenceServerServiceTest {

    @Autowired
    private DigitalSignatureClient digitalSignatureClient;


    @Test
    public void testDigitalSignature() {

        try {
            digitalSignatureClient.getDigitalSignature();
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(404);
        }

        DigitalSignature digitalSignature = new DigitalSignature();
        digitalSignature.setPassword("test");
        digitalSignature.setCertificateName("test");
        digitalSignature.setReason("test");
        digitalSignature.setLocation("test");
        digitalSignature.setContactInfo("test");
        digitalSignature.setBase64EncodedPrivateKey("zzz");

        var savedDigitalSignature = digitalSignatureClient.saveDigitalSignature(digitalSignature);

        var loadedSignature = digitalSignatureClient.getDigitalSignature();
        // encrypted

        var dvm = new DigitalSignatureViewModel();
        BeanUtils.copyProperties(loadedSignature, dvm);
        dvm.setReason("new test");
        digitalSignatureClient.updateDigitalSignature(dvm);
        loadedSignature = digitalSignatureClient.getDigitalSignature();
        assertThat(loadedSignature.getReason()).isEqualTo("new test");

        digitalSignatureClient.deleteDigitalSignature();
        try {
            digitalSignatureClient.getDigitalSignature();
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(404);
        }

    }


    @Autowired
    private EncryptionDecryptionService encryptionDecryptionService;

    @Test
    @SneakyThrows
    public void testDigitalSignatureKms() {

        // Arrange
        final String certificateName = "certificateName";
        final String kmsKeyId = "kmsKeyId";
        final String kmsAccessKey = "kmsAccessKey";
        final String kmsRegion = "kmsRegion";
        final String kmsSecretKey = "kmsSecretKey";
        final String kmsServiceEndpoint = "kmsServiceEndpoint";
        final byte[] certificate = Files.readAllBytes(new ClassPathResource("files/TestCert.cer").getFile().toPath());

        var data =encryptionDecryptionService.encrypt(new String(certificate));
        var res = encryptionDecryptionService.decrypt(data);

        DigitalSignatureKms digitalSignature = DigitalSignatureKms.builder()
                .certificateName(certificateName)
                .kmsKeyId(kmsKeyId)
                .kmsAccessKey(kmsAccessKey)
                .kmsRegion(kmsRegion)
                .kmsSecretKey(kmsSecretKey)
                .kmsServiceEndpoint(kmsServiceEndpoint)
                .certificate(new String(certificate))
                .build();

        // Act and Assert: Get not existing
        try {
            digitalSignatureClient.getDigitalSignatureKms();
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(404);
        }

        // Act and Assert: Save
        var savedDigitalSignature = digitalSignatureClient.saveDigitalSignatureKms(digitalSignature);

        assertThat(savedDigitalSignature.getKmsAccessKey()).isEqualTo(digitalSignature.getKmsAccessKey());
        assertThat(savedDigitalSignature.getKmsKeyId()).isEqualTo(digitalSignature.getKmsKeyId());
        assertThat(savedDigitalSignature.getKmsRegion()).isEqualTo(digitalSignature.getKmsRegion());
        assertThat(savedDigitalSignature.getCertificateName()).isEqualTo(digitalSignature.getCertificateName());
        assertThat(savedDigitalSignature.getKmsServiceEndpoint()).isEqualTo(digitalSignature.getKmsServiceEndpoint());

        // Act and Assert: Get existing
        var loadedDigitalSignature = digitalSignatureClient.getDigitalSignatureKms();

        assertThat(loadedDigitalSignature.getKmsAccessKey()).isEqualTo(digitalSignature.getKmsAccessKey());
        assertThat(loadedDigitalSignature.getKmsKeyId()).isEqualTo(digitalSignature.getKmsKeyId());
        assertThat(loadedDigitalSignature.getKmsRegion()).isEqualTo(digitalSignature.getKmsRegion());
        assertThat(loadedDigitalSignature.getCertificateName()).isEqualTo(digitalSignature.getCertificateName());
        assertThat(loadedDigitalSignature.getKmsServiceEndpoint()).isEqualTo(digitalSignature.getKmsServiceEndpoint());

        // Act and Assert: Delete
        digitalSignatureClient.deleteDigitalSignatureKms();
        try {
            digitalSignatureClient.getDigitalSignatureKms();
        } catch (FeignException.FeignClientException e) {
            assertThat(e.status()).isEqualTo(404);
        }

    }

}
