package com.malk.service.eiam.impl;

import com.malk.server.common.McException;
import com.malk.server.eiam.EiamConf;
import com.malk.server.eiam.EiamTokenResponse;
import com.malk.service.eiam.EiamClient;
import com.malk.service.eiam.EiamService;
import com.malk.utils.UtilToken;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * EIAM Token 缓存服务。
 */
@Service
public class EiamServiceImpl implements EiamService {

    @Autowired
    private EiamConf eiamConf;

    @Autowired
    private EiamClient eiamClient;

    @Override
    public String getAccessToken() {
        validateConfig();
        String key = eiamConf.getInstanceId() + ":" + eiamConf.getApplicationId();
        String cached = UtilToken.get(EiamConf.NS, key);
        if (StringUtils.isNotBlank(cached)) {
            return cached;
        }
        EiamTokenResponse response = eiamClient.generateToken(
                eiamConf.getInstanceId(), eiamConf.getApplicationId(), "client_credentials",
                eiamConf.getClientId(), eiamConf.getClientSecret(), null);
        if (response == null || StringUtils.isBlank(response.getAccessToken())) {
            String message = response == null ? "EIAM Token 响应为空"
                    : StringUtils.defaultIfBlank(response.getErrorDescription(), response.getError());
            throw new McException("EIAM_TOKEN_ERROR", message);
        }
        if (response.getExpiresIn() == null || response.getExpiresIn() <= 0) {
            throw new McException("EIAM_TOKEN_ERROR", "EIAM Token 响应缺少有效 expires_in");
        }
        long ttlSeconds = Math.max(1L, response.getExpiresIn() - EiamConf.TOKEN_AHEAD_SECONDS);
        UtilToken.put(EiamConf.NS, key, response.getAccessToken(), ttlSeconds * 1000L);
        return response.getAccessToken();
    }

    private void validateConfig() {
        if (StringUtils.isAnyBlank(eiamConf.getBaseUrl(), eiamConf.getInstanceId(),
                eiamConf.getApplicationId(), eiamConf.getClientId(), eiamConf.getClientSecret())) {
            throw new McException("EIAM_CONFIG_ERROR", "EIAM 配置不完整");
        }
    }
}
