package com.hys.app.converter.oauth2;

import com.hys.app.framework.util.BeanUtils;
import com.hys.app.framework.util.CollectionUtils;
import com.hys.app.model.base.KeyValue;
import com.hys.app.model.oauth2.dos.OAuth2AccessTokenDO;
import com.hys.app.model.oauth2.dos.OAuth2ApproveDO;
import com.hys.app.model.oauth2.dos.OAuth2ClientDO;
import com.hys.app.model.oauth2.vo.OAuth2OpenAccessTokenRespVO;
import com.hys.app.model.oauth2.vo.OAuth2OpenAuthorizeInfoRespVO;
import com.hys.app.model.oauth2.vo.OAuth2OpenCheckTokenRespVO;
import com.hys.app.oauth2.utils.OAuth2Utils;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * OAuth2Open的 converter
 *
 * @author 张崧
 * @since 2024-02-20
 */
@Mapper
public interface OAuth2OpenConvert {

    OAuth2OpenConvert INSTANCE = Mappers.getMapper(OAuth2OpenConvert.class);

    default OAuth2OpenAccessTokenRespVO convert(OAuth2AccessTokenDO bean) {
        OAuth2OpenAccessTokenRespVO respVO = BeanUtils.toBean(bean, OAuth2OpenAccessTokenRespVO.class);
        respVO.setTokenType(OAuth2Utils.AUTHORIZATION_BEARER.toLowerCase());
        respVO.setExpiresIn(OAuth2Utils.getExpiresIn(bean.getExpiresTime()));
        respVO.setScope(OAuth2Utils.buildScopeStr(bean.getScopes()));
        return respVO;
    }

    default OAuth2OpenCheckTokenRespVO convert2(OAuth2AccessTokenDO bean) {
        OAuth2OpenCheckTokenRespVO respVO = BeanUtils.toBean(bean, OAuth2OpenCheckTokenRespVO.class);
        respVO.setExp(bean.getExpiresTime());
        return respVO;
    }

    default OAuth2OpenAuthorizeInfoRespVO convert(OAuth2ClientDO client, List<OAuth2ApproveDO> approves) {
        // 构建 scopes
        List<KeyValue<String, Boolean>> scopes = new ArrayList<>(client.getScopes().size());
        Map<String, OAuth2ApproveDO> approveMap = CollectionUtils.convertMap(approves, OAuth2ApproveDO::getScope);
        client.getScopes().forEach(scope -> {
            OAuth2ApproveDO approve = approveMap.get(scope);
            scopes.add(new KeyValue<>(scope, approve != null ? approve.getApproved() : false));
        });
        // 拼接返回
        return new OAuth2OpenAuthorizeInfoRespVO(
                new OAuth2OpenAuthorizeInfoRespVO.Client(client.getName(), client.getLogo()), scopes);
    }

}
