package com.hys.app.framework.apptoken.impl;
import com.hys.app.framework.apptoken.*;
import com.hys.app.framework.apptoken.model.AccessToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hys.app.framework.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * access token管理接接口实现
 * 对token进行统一的缓存处理
 * @author kingapex
 * @version 1.0
 * @data 2021/8/22 16:33
 **/
@Service
public class AccessTokenManagerImpl implements AccessTokenManager {
    private final Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    private AccessTokenCache accessTokenCache;

    @Autowired
    AccessTokenGetterFactory accessTokenGetterFactory;




    /**
     * 从缓存处获取，如果没有由微信获取，并存缓存
     * @return
     */
    @Override
    public String getToken(AccessTokenIdentifier accessTokenIdentifier) {


        //由缓存处获取token
        AccessToken accessToken = accessTokenCache.get(accessTokenIdentifier);

        Long now = DateUtil.getDateline();

        //如果token已经失效则重新获取token
        if ( accessToken== null || accessToken.getExpires()<=now ) {

            accessToken = this.getAndCache(accessTokenIdentifier);

            return accessToken.getToken();
        }

        return accessToken.getToken();
    }


    /**
     * 强制刷新token并返回
     * @return
     */
    @Override
    public String refreshToken(AccessTokenIdentifier accessTokenIdentifier) {
        logger.debug("强制刷新" );

        AccessToken accessToken = this.getAndCache(accessTokenIdentifier);

        return accessToken.getToken();
    }

    /**
     * 调用第三方服务api 获取token
     * @param accessTokenIdentifier token的唯一标识
     * @return token
     */
    private AccessToken getAndCache(AccessTokenIdentifier accessTokenIdentifier) {

        AccessTokenGetter accessTokenGetter = accessTokenGetterFactory.getBean(accessTokenIdentifier.getAppEnum());

        //调用token获取器，由第三个服务api获取token
        AccessToken  accessToken =accessTokenGetter.getToken(accessTokenIdentifier);

        //存入缓存
        accessTokenCache.put(accessTokenIdentifier, accessToken);

        return accessToken;
    }


}
