package com.tsi.api.server.service;

import com.tsi.api.server.dto.KafkaTokenDto;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Base64;
import java.util.Date;

@Slf4j
@Service
public class TscSsipKafkaTokenService {

    private String secretKey = "kafka-tsc-secret-key";

    @PostConstruct
    protected void init() {
//        log.info("************************************************ before: {}", this.secretKey);
        this.secretKey = Base64.getEncoder().encodeToString(this.secretKey.getBytes());
//        log.info("************************************************ -after: {}", this.secretKey);
    }

    // Access Token create
    public KafkaTokenDto generateToken(String apiToken, String uid, String pwd, String role) {
        long tokenPeriod = 1000L * 60L * 10L;                       // 10분
        long refreshPeriod = 1000L * 60L * 60L * 24L * 30L * 3L;    // 3주

        Claims claims = Jwts.claims().setId(uid).setSubject(pwd);
        claims.put("role", role);
        claims.put("apiToken", apiToken);

        Date now = new Date();
        return new KafkaTokenDto(
                Jwts.builder()
                        .setClaims(claims)
                        .setIssuedAt(now)
                        .setExpiration(new Date(now.getTime() + tokenPeriod))
                        .signWith(SignatureAlgorithm.HS256, this.secretKey)
                        .compact(),
                Jwts.builder()
                        .setClaims(claims)
                        .setIssuedAt(now)
                        .setExpiration(new Date(now.getTime() + refreshPeriod))
                        .signWith(SignatureAlgorithm.HS256, this.secretKey)
                        .compact());
    }

    public KafkaTokenDto decode(String token) {
        try {
            Jws<Claims> claims = Jwts.parser()
                    .setSigningKey(this.secretKey)
                    .parseClaimsJws(token);

            KafkaTokenDto kafkaTokenDto = new KafkaTokenDto();
            kafkaTokenDto.setApiToken((String) claims.getBody().get("apiToken"));
            kafkaTokenDto.setUid(claims.getBody().getId());
            kafkaTokenDto.setPwd(claims.getBody().getSubject());

            //log.info("{}", claims.toString());
            return kafkaTokenDto;
        }
        catch (Exception e) {
            return null;
        }
    }
    public boolean verifyToken(String token) {
        try {
            Jws<Claims> claims = Jwts.parser()
                    .setSigningKey(this.secretKey)
                    .parseClaimsJws(token);
            return claims.getBody()
                    .getExpiration()
                    .after(new Date());
        }
        catch (Exception e) {
            return false;
        }
    }

    public String getUid(String token) {
        return Jwts.parser().setSigningKey(this.secretKey).parseClaimsJws(token).getBody().getSubject();
    }
}
