package com.duiba.tuia.youtui.web.tongdun;

import com.alibaba.fastjson.JSON;
import com.duiba.tuia.youtui.web.constant.Constants;
import com.duiba.tuia.youtui.web.log.InnerLogService;
import com.duiba.tuia.youtui.web.tool.http.HttpAsyncClientPool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author : chengdeman
 * @Description :
 * @Date : 17/5/10
 */
@Service
public class FraudApiInvoker {

    private final Log           log = LogFactory.getLog(this.getClass());

    @Autowired
    private HttpAsyncClientPool httpAsyncClientPool;

    public void invoke(final Map<String, Object> params) {
        HttpPost httpPost = new HttpPost(FraudApiRequest.API_URL);

        List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size());
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (null != entry.getValue()) {
                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
                pairList.add(pair);
            }
        }
        httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8")));
        FutureCallback<HttpResponse> handler = new FutureCallback<HttpResponse>() {

            @Override
            public void completed(HttpResponse result) {
                try {
                    int statusCode = result.getStatusLine().getStatusCode();
                    if (statusCode != HttpStatus.SC_OK) {
                        log.warn("[FraudApiInvoker] invoke failed, response status: " + statusCode);
                        return;
                    }
                    HttpEntity entity = result.getEntity();
                    if (entity == null) {
                        log.warn("[FraudApiInvoker] invoke failed, response output is null!");
                        return;
                    }
                    InnerLogService.antiCheatingLog(params, JSON.parseObject(EntityUtils.toString(entity, "utf-8")));
                } catch (Exception e) {
                    log.error("[FraudApiInvoker] invoke throw exception, details: ", e);
                } finally {
                    if (result != null) {
                        try {
                            EntityUtils.consume(result.getEntity());
                        } catch (IOException e) {
                            log.warn("[HttpEntity] consume failed, detial: ", e);
                        }
                    }
                }
            }

            @Override
            public void failed(Exception ex) {
                log.error("[FraudApiInvoker] invoke throw exception, details: ", ex);
            }

            @Override
            public void cancelled() {
                log.error("[FraudApiInvoker] has been cancelled.");
            }
        };
        httpAsyncClientPool.submit(httpPost, handler);

    }

    public void invokeTouTiao(String url, final Map<String, Object> params,Long  consumerId,Long appId) {
        HttpPost httpPost = new HttpPost(url);

        List<NameValuePair> pairList = paramToList(params);
        httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8")));
        FutureCallback<HttpResponse> handler = new FutureCallback<HttpResponse>() {

            @Override
            public void completed(HttpResponse result) {
                try {
                    int statusCode = result.getStatusLine().getStatusCode();
                    HttpEntity entity = result.getEntity();
                    if (statusCode != HttpStatus.SC_OK || entity == null) {
                        log.warn("[FraudApiInvoker] invoke failed, response status: " + statusCode+" or response output is null!");
                        return;
                    }
                    params.put("consumerId",consumerId);
                    params.put("appId",appId);
                    if(url.contains(Constants.CUSTOM.TOUTIAO_AD_EVENT_UP_HTTP_DOMAIN)){
                        InnerLogService.tadClickLog(params, JSON.parseObject(EntityUtils.toString(entity, "utf-8")));
                    }else if(url.contains(Constants.CUSTOM.TOUTIAO_DIS_LIKE_HTTP_DOMAIN)){
                        //InnerLogService.tDisLikeLog(params, JSON.parseObject(EntityUtils.toString(entity, "utf-8")));// 用户不喜欢点击
                    }else{
                        InnerLogService.tNewsLog(params, JSON.parseObject(EntityUtils.toString(entity, "utf-8")));
                    }
                } catch (Exception e) {
                    log.error("[FraudApiInvoker] invokeTouTiao throw exception, details: ", e);
                } finally {
                    if (result != null) {
                        try {
                            EntityUtils.consume(result.getEntity());
                        } catch (IOException e) {
                            log.warn("[HttpEntity] consume failed, detial: ", e);
                        }
                    }
                }
            }

            @Override
            public void failed(Exception ex) {
                log.error("[FraudApiInvoker] invokeTouTiao throw exception, details: ", ex);
            }

            @Override
            public void cancelled() {
                log.error("[FraudApiInvoker] invokeTouTiao has been cancelled.");
            }
        };
        httpAsyncClientPool.submit(httpPost, handler);

    }

    /**
     * map参数转换为
     */
    private  List<NameValuePair> paramToList(final Map<String, Object> params){
        List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size());
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (null != entry.getValue()) {
                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString());
                pairList.add(pair);
            }
        }

        return pairList;
    }

}
