package de.adorsys.opba.api.security.service;

import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.JWSVerifier;
import de.adorsys.opba.api.security.internal.EnableTokenBasedApiSecurity;
import de.adorsys.opba.api.security.internal.config.TppTokenProperties;
import de.adorsys.opba.api.security.internal.service.TokenBasedAuthService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.validation.annotation.Validated;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.time.Duration;
import java.util.Base64;

import static de.adorsys.opba.api.security.internal.config.ConfigConst.API_CONFIG_PREFIX;
import static org.assertj.core.api.Assertions.assertThat;

@Slf4j
@ActiveProfiles("test")
@SpringBootTest(classes = TokenSignVerifyTest.TestConfig.class)
public class TokenSignVerifyTest {
    private static final Duration DURATION_10M = Duration.ofMinutes(10);

    @Autowired
    private TokenBasedAuthService psuAuthService;

    @Autowired
    private JWSVerifier verifier;

    @Test
    @SneakyThrows
    void signVerifyTest() {
        String message = "some data";

        String token = psuAuthService.generateToken(message, DURATION_10M);

        JWSObject jwsObject = JWSObject.parse(token);
        assertThat(jwsObject.verify(verifier)).isTrue();
        assertThat(jwsObject.getPayload().toJSONObject().get("sub")).isEqualTo(message);
    }

    @Test
    @SneakyThrows
    @Disabled
    void generateNewTppKeyPair() {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        generator.initialize(2048);
        KeyPair keyPair = generator.genKeyPair();

        String privateKeyString = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
        String publicKeyString = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());

        log.info("Private key:" + privateKeyString);
        log.info("Public key:" + publicKeyString);

    }

    @Configuration
    @EnableTokenBasedApiSecurity
    public static class TestConfig {

        @Validated
        @Configuration
        @ConfigurationProperties(API_CONFIG_PREFIX + "security")
        public class TppTokenPropertiesConfig extends TppTokenProperties {
        }
    }
}
