/*
 * Examples for Java
 *
 * Copyright (c) 2021. Elex. All Rights Reserved.
 * https://www.elex-project.com/
 */

package kr.pe.elex.examples;

import io.jsonwebtoken.Header;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.CompressionAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.junit.jupiter.api.Test;

import javax.crypto.SecretKey;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Date;
import java.util.Random;

import static org.junit.jupiter.api.Assertions.*;

class SampleTest {
	@Test
	void keyTest(){
		SecretKey secretKey = JwtsSample.generateSecretKey();

		byte[] rawKey = secretKey.getEncoded();
		String alg = secretKey.getAlgorithm();

		SecretKey secKey = JwtsSample.getSecretKey(rawKey, alg);

		String token = Jwts.builder()
				.header().type("JWT")
				.and()
				.issuer("Elex")
				.expiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
				.claim("userId", 3)
				.subject("hello")
				.signWith(secretKey)
				.compact();

		String subject = Jwts.parser()
				.verifyWith(secKey)
				.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
				.build().parseSignedClaims(token).getPayload().getSubject();
		System.out.println(subject);
	}
@Test
void test2(){
	final SecretKey signingKey = Jwts.SIG.HS384.key().build();
	String token = Jwts.builder()
			.header().type("JWT")
			.and()
			.issuer("Elex")
			.expiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
			.claim("userId", 3)
			.subject("hello")
			.signWith(signingKey)
			.compact();
	String payload = JwtsSample.decodeToken(token);

	System.out.println(payload);

	//String sub = JwtsSample.decodeToken2(token);
	//System.out.println(sub);
}
	@Test
	void test() throws NoSuchAlgorithmException, InvalidKeySpecException {
		byte[] key = new byte[32];
		new Random().nextBytes(key);
		//final SecretKey signingKey = Keys.hmacShaKeyFor(key);
		KeyPair keyPair = Jwts.SIG.RS384.keyPair().build();
		PrivateKey privateKey = keyPair.getPrivate();
		PublicKey publicKey = keyPair.getPublic();
		String base64PublicKey = Base64.getEncoder().encodeToString(publicKey.getEncoded());

		String jwt = Jwts.builder()
				.header().type("JWT")
				.and()
				.issuer("Elex")
				.expiration(Date.from(Instant.now().plus(3, ChronoUnit.HOURS)))
				.claim("userId", 3)
				.signWith(keyPair.getPrivate())
				.compact();
		System.out.println(jwt);

		X509EncodedKeySpec ukeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey));
		PublicKey pKey = KeyFactory.getInstance("RSA").generatePublic(ukeySpec);

		Integer userId = Jwts.parser()
				.verifyWith(pKey)
				.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
				.build()
				.parseSignedClaims(jwt).getPayload().get("userId", Integer.class);
		System.out.println(userId);
		String alg = Jwts.parser()
				.verifyWith(pKey)
				.requireIssuer("Elex") // 토큰의 Issuer 일치 여부 확인
				.build()
				.parseSignedClaims(jwt).getHeader().getAlgorithm();
		System.out.println(alg);
	}
}
