/**
 * All rights Reserved, Designed By www.freemud.cn
 *
 * @Title: AsyOperationService
 * @Package cn.freemud.service
 * @Description:
 * @author: song.cai
 * @date: 2019/1/21 16:38
 * @version V1.0
 * @Copyright: 2019 www.freemud.cn Inc. All rights reserved.
 * 注意：本内容仅限于上海非码科技内部传阅，禁止外泄以及用于其他的商业目
 */

package cn.freemud.service.impl;

import cn.freemud.amqp.Header;
import cn.freemud.amqp.MQMessage;
import cn.freemud.amqp.MQService;
import cn.freemud.base.util.JsonUtil;
import cn.freemud.comm.druid.MyMapper;
import cn.freemud.entities.db.SaasLinkMonitorLog;
import cn.freemud.entities.vo.ThirdPartLogVo;
import cn.freemud.service.AsyOperationService;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ErrorLog;
import lombok.Getter;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class AsyOperationServiceImpl implements AsyOperationService {

    public static final int threads = Runtime.getRuntime().availableProcessors() + 1;
    public static final long aliveTime = 5L;


    public final static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(threads, threads, aliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10000));
    @Autowired
    MQService mqService;
    @Value("${link_log_queue}")
    private String linkLogQueue;
    @Value("${link_log_exchange}")
    private String linkLogExchange;

    private static volatile String appName = null;

    @Override
    public <T> void insertData(MyMapper<T> myMapper, T t) {
        threadPoolExecutor.execute(() -> {
            try {
                myMapper.insert(t);
            } catch (Exception ex) {

            }
        });
    }

    /**
     * 创建Log实体并发送到MQ
     *
     * @param thirdPartLogVo
     * @param trackingId
     * @param timeConsumed
     * @param responseString
     */
    @Override
    public void createLogBeanAndSend2MQ(ThirdPartLogVo thirdPartLogVo, String trackingId, long timeConsumed, String responseString, boolean isTimeoutRequest) {

        threadPoolExecutor.execute(() -> {
            if(!Objects.equals(thirdPartLogVo, null)) {
                return;
            }
            try {
                // 不是请求超时的需要过滤活动不存在的返回
                if (!isTimeoutRequest
                        && StringUtils.isNotEmpty(responseString)) {
                    for (IgnoreRequest ignoreRequest : IgnoreRequest.values()) {
                        if (StringUtils.equalsIgnoreCase(ignoreRequest.getServiceName(), thirdPartLogVo.getThirdPartName())
                                && StringUtils.equals(ignoreRequest.getUri(), thirdPartLogVo.getUri())) {
                            String statusValue = JSONObject.parseObject(responseString).getString(ignoreRequest.getStatusKey());
                            if (ignoreRequest.getIgnoreValues().contains(statusValue)) {
                                return;
                            }
                        }
                    }
                }
                SaasLinkMonitorLog saasLinkMonitorLog = new SaasLinkMonitorLog();
                saasLinkMonitorLog.setTrackingId(trackingId);
                saasLinkMonitorLog.setServiceName(thirdPartLogVo.getThirdPartName());
                saasLinkMonitorLog.setUri(thirdPartLogVo.getUri());
                saasLinkMonitorLog.setCostTimeMili(timeConsumed);
                saasLinkMonitorLog.setRequest(thirdPartLogVo.getRequestBody());
                saasLinkMonitorLog.setResponse(responseString);
                // 发送到MQ
                Header header = new Header();
                MQMessage<SaasLinkMonitorLog> message = new MQMessage<>(header, saasLinkMonitorLog);
                mqService.convertAndSend(linkLogExchange, linkLogQueue, message);
            } catch (Exception ex) {
                ErrorLog.errorConvertJson(this.getClass(), JsonUtil.toJSONString(thirdPartLogVo),ex);
//                ErrorLog.printErrorLog("MQLOGERROR","",thirdPartLogVo,ex);
            }
        });
    }

    @Getter
    public enum IgnoreRequest {
        ACTIVITY_QUERY("ACTIVITY", "/activity/query", "statusCode", "601"),
        ACTIVITIES_GET_ACTIVITIES_BY_STOREID("PROMOTION-ACTIVITIES", "/activities/getActivitiesByStoreId", "code", "50000");

        IgnoreRequest(String serviceName, String uri, String statusKey, String... ignoreValue) {
            this.serviceName = serviceName;
            this.uri = uri;
            this.statusKey = statusKey;
            this.ignoreValues = Arrays.asList(ignoreValue);
        }

        /**
         * 服务名称
         */
        private String serviceName;
        /**
         * uri
         */
        private String uri;
        /**
         * 表明状态的字段key
         */
        private String statusKey;
        /**
         * 需要忽略的字段名
         */
        private List<String> ignoreValues;
    }
}
