package com.gic.haoban.manage.web.utils.data;

import com.alibaba.fastjson.JSONObject;
import com.gic.dubbo.entity.ProviderLocalTag;
import com.gic.web.common.utils.ExecutorPoolSingleton;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * @Author guojx
 * @Date 2024/1/12 13:41
 */
@Slf4j
public class ConcurrencyUtils {

    public static Map<String, List<JSONObject>> concurrencyDataForMap(List<MapThreadHandlerRequest> list) {
        Map<String, List<JSONObject>> resultMap = new HashMap<>();
        if (CollectionUtils.isEmpty(list)) {
            return resultMap;
        }
        ProviderLocalTag providerLocalTag = ProviderLocalTag.tag.get();
        String traceId = providerLocalTag.traceId;
        for (MapThreadHandlerRequest temp : list) {
            temp.setTraceId(traceId);
        }
        long startTime = System.currentTimeMillis();
        try {
            List<Future<Map<String, List<JSONObject>>>> futures2 = ExecutorPoolSingleton.getInstance().getExecutorService().invokeAll(list);
            log.info("调用API耗时 : " + (System.currentTimeMillis() - startTime));
            for (Future<Map<String, List<JSONObject>>> future : futures2) {
                try {
                    Map<String, List<JSONObject>> map = future.get();
                    if (map != null) {
                        map.forEach((k, v) -> {
                            resultMap.put(k, v);
                        });
                    }
                } catch (Exception e) {
                    log.warn("remote Api failed ： {}", e.getCause().getMessage());
                }
            }
            long endTime = System.currentTimeMillis();
            log.info("耗时 : " + (endTime - startTime));
        } catch (Exception e) {
            log.warn("并发调用错误:{}", e.getMessage(), e);
        }
        return resultMap;
    }

    public static List<JSONObject> concurrencyData(List<ThreadHandlerRequest> list) {
        List<JSONObject> resultList = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return resultList;
        }

        List<MapThreadHandlerRequest> mapParam = new ArrayList<>();
        for (int i = 0, len = list.size(); i < len; i++) {
            MapThreadHandlerRequest res = new MapThreadHandlerRequest(list.get(i).getJsonObject(),
                    list.get(i).getApolloKey(), "data" + i);
            mapParam.add(res);
        }
        Map<String, List<JSONObject>> map = concurrencyDataForMap(mapParam);
        if (map != null) {
            map.forEach((k, v) -> {
                if (CollectionUtils.isNotEmpty(v)) {
                    resultList.addAll(v);
                }
            });
        }
        return resultList;
    }
}
