package cn.ibizlab.r7.runtime.runtimemgr.security.token;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.*;

public class TokenManager {
    private static final long serialVersionUID = -3301605591108950415L;
    private Clock clock = DefaultClock.INSTANCE;

    @Value("${ibiz.jwt.secret:ibzsecret}")
    private String secret;

    @Value("${ibiz.jwt.expiration:7200000}")
    private Long expiration;

    @Value("${ibiz.jwt.header:Authorization}")
    private String tokenHeader;

    public UsernamePasswordAuthenticationToken parseToken(String strToken){
        Claims claims = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(strToken)
                .getBody();
        List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(claims.getSubject(), null, authorities);
        return token ;
    }

    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        final Date createdDate = clock.now();
        final Date expirationDate = calculateExpirationDate(createdDate);
        Collection<? extends GrantedAuthority> authorities = userDetails.getAuthorities();
        StringBuffer as = new StringBuffer();
        for (GrantedAuthority authority : authorities) {
            as.append(authority.getAuthority())
                    .append(",");
        }
        claims.put("authorities",as) ;

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userDetails.getUsername())
                .setIssuedAt(createdDate)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
    }

    private Date calculateExpirationDate(Date createdDate) {
        return new Date(createdDate.getTime() + expiration);
    }

    public String refreshToken(String strToken) {
        return "" ;
    }

    public Boolean validateToken(String strToken) {
        return true ;
    }

}
