/*
 * Copyright (c) 2024. Elex. All Rights Reesrved.
 * https://www.elex-project.com/
 */

package kr.pe.elex.examples;

import io.jsonwebtoken.Header;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;

import javax.crypto.SecretKey;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.time.ZonedDateTime;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * https://github.com/jwtk/jjwt
 */
public class JwtsSample {

	public static SecretKey generateSecretKey() {
		return Jwts.SIG.HS256.key().build();

	}

	public static KeyPair generateKeyPair() {
		return Jwts.SIG.RS512.keyPair().build();

	}


	public static String generateToken(final SecretKey key) {
		return Jwts.builder()
				.header().type(Header.JWT_TYPE)
				.and()
				.id(UUID.randomUUID().toString())
				.issuedAt(Date.from(ZonedDateTime.now().toInstant()))
				.issuer("Elex Company")
				.subject("Hello")
				.audience().add("Charlie")
				.and()
				.expiration(Date.from(ZonedDateTime.now().plusHours(2).toInstant()))
				.notBefore(Date.from(ZonedDateTime.now().toInstant()))
				.signWith(key)
				.compact();
	}

	public static String generateToken(final PrivateKey key) {
		return Jwts.builder()
				.header().type(Header.JWT_TYPE)
				.and()
				.id(UUID.randomUUID().toString())
				.issuedAt(Date.from(ZonedDateTime.now().toInstant()))
				.issuer("Elex Company")
				.subject("Hello")
				.audience().add("Charlie")
				.and()
				.expiration(Date.from(ZonedDateTime.now().plusHours(2).toInstant()))
				.notBefore(Date.from(ZonedDateTime.now().toInstant()))
				.signWith(key, Jwts.SIG.RS512)
				.compact();
	}

	public static String parseToken(final String token, final SecretKey key) throws JwtException {
		try {
			return Jwts.parser().verifyWith(key).build()
					.parseSignedClaims(token)
					.getPayload().getSubject();
		} catch (JwtException e) {
			e.printStackTrace();
			throw e;
		}
	}

	public static String parseToken(final String token, final PublicKey key) throws JwtException {
		try {
			return Jwts.parser()
					.verifyWith(key)
					.requireIssuer("Elex")
					.build()
					.parseSignedClaims(token)
					.getPayload().getSubject();
		} catch (JwtException e) {
			e.printStackTrace();
			throw e;
		}
	}

	public static void main(String... args) {
		SecretKey key = generateSecretKey();
		System.out.println(Base64.getEncoder().encodeToString(key.getEncoded()));

		String token = generateToken(key);
		System.out.println(token);

		String subject = parseToken(token, key);
		System.out.println(subject);

	}
}
