package com.gitee.sop.gateway.service.manager.impl;

import com.gitee.sop.gateway.dao.entity.IsvInfo;
import com.gitee.sop.gateway.dao.entity.IsvMerchant;
import com.gitee.sop.gateway.dao.mapper.IsvInfoMapper;
import com.gitee.sop.gateway.dao.mapper.IsvMerchantMapper;
import com.gitee.sop.gateway.service.manager.IsvManager;
import com.gitee.sop.gateway.service.manager.dto.IsvDTO;
import com.gitee.sop.gateway.util.CopyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 六如
 */
@Slf4j
public class LocalIsvManagerImpl implements IsvManager {

    private static final Map<String, Optional<IsvDTO>> CACHE = new ConcurrentHashMap<>();

    @Autowired
    protected IsvInfoMapper isvInfoMapper;
    @Autowired
    protected IsvMerchantMapper isvMerchantMapper;

    @Override
    public IsvDTO getIsv(String appId) {
        return CACHE.computeIfAbsent(appId, k -> {
            IsvDTO isvDTO = search(appId);
            return Optional.ofNullable(isvDTO);
        }).orElse(null);
    }

    @Override
    public Map<String, IsvDTO> refresh(Collection<String> appIds) {
        log.info("刷新isv, appId={}", appIds);
        if (CollectionUtils.isEmpty(appIds)) {
            return Collections.emptyMap();
        }
        Map<String, IsvDTO> map = new HashMap<>(appIds.size() * 2);
        for (String appId : appIds) {
            IsvDTO isvDTO = search(appId);
            cache(appId, isvDTO);
        }
        return map;
    }

    protected IsvDTO search(String appId) {
        IsvInfo isvInfo = isvInfoMapper.getByAppId(appId);
        IsvDTO isvDTO = CopyUtil.copyBean(isvInfo, IsvDTO::new);
        IsvMerchant isvMerchant = isvMerchantMapper.get(IsvMerchant::getAppId, appId);
        if (isvMerchant != null) {
            isvDTO.setMerchantCode(isvMerchant.getMerchantCode());
        }
        return isvDTO;
    }

    protected void cache(String appId, IsvDTO isvDTO) {
        CACHE.put(appId, Optional.ofNullable(isvDTO));
        log.info("更新isv本地缓存, isvDTO={}", isvDTO);
    }

}
