package com.fshark.overseas.advert.processor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fshark.overseas.advert.modle.AppsFlyerEvent;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.util.Collector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

public class ParseEventProcessor implements FlatMapFunction<String, AppsFlyerEvent> {

    private Logger logger = LoggerFactory.getLogger(ParseEventProcessor.class);
    @Override
    public void flatMap(String value, Collector<AppsFlyerEvent> out) throws Exception {
        try {
            JSONObject jsonObject = JSON.parseObject(value);
            String message = jsonObject.getString("message");

            String parseLine = "";
            try {
                parseLine = parseLine(message);
            } catch (Exception e) {

            }
            if (StringUtils.isBlank(parseLine)) {
                return;
            }
            AppsFlyerEvent appsFlyerEvent = AppsFlyerEvent.parse(parseLine);
            if (appsFlyerEvent != null) {
                out.collect(appsFlyerEvent);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info(value);
        }
    }

    private String parseLine(String log) {
        if (!StringUtils.isEmpty(log)) {
            if (log.contains("GET")) {
                String[] tmp = log.split("GET /\\?");
                if (tmp.length > 1) {
                    String params = tmp[1].split("HTTP/1.1")[0].trim();
                    if (!StringUtils.isEmpty(params)) {
                        if (params.indexOf("=") > 1) {
                            //参数的=没有进行编码，则可以先按照&符号来分隔取得每个参数
                            return splitDecode(params);
                        } else {
                            //没有=标识所有的特式字符都编码了，需要先解码再来获取参数
                            return decodeParse(params);
                        }
                    }
                }
            } else {
                if (log.indexOf("=") > 1) {
                    //参数的=没有进行编码，则可以先按照&符号来分隔取得每个参数
                    return splitDecode(log);
                } else {
                    //没有=标识所有的特式字符都编码了，需要先解码再来获取参数
                    return decodeParse(log);
                }
            }

        }
        return null;
    }

    /**
     * 先按&将每个参数取出，然后对value进行decode取得值
     *
     * @param url
     * @return
     */
    private String splitDecode(String url) {
        String[] params = url.split("&");
        if (params.length > 0) {
            JSONObject json = new JSONObject();
            for (String p : params) {
                String[] kv = p.split("=");
                String v = "";
                if (kv.length < 2 || StringUtils.isBlank(kv[1])) {
                    v = "";
                } else {
                    try {
                        v = URLDecoder.decode(kv[1], "UTF-8");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                json.put(kv[0], v);
            }
            json.put("log_transport_type", "retransmission");
            return json.toJSONString();
        }
        return null;
    }

    /**
     * 先decode参数，然后根据字符解析出每个参数
     *
     * @param url
     * @return
     */
    private String decodeParse(String url) {
        try {
            String params = URLDecoder.decode(url, "UTF-8");
            if (params.length() > 0) {
                String s = params;
                List<String> list = new ArrayList<>();
                StringBuffer buffer = new StringBuffer();
                StringBuffer tmp = new StringBuffer();
                boolean f1 = false;
                boolean f2 = false;
                for (int i = 0; i < s.length(); i++) {
                    char c = s.charAt(i);

                    if ("&".equals(String.valueOf(c))) {
                        if (f1) {
                            if (!f2) {
                                buffer.append(tmp.toString());
                                f2 = true;
                            } else {
                                list.add(buffer.toString());
                                buffer = tmp;
                                f2 = true;
                            }
                            tmp = new StringBuffer();
                            f1 = false;
                        } else {
                            if (f2) {
                                buffer.append(c).append(tmp.toString());
                                tmp = new StringBuffer();
                            } else {
                                //key中包含&这种数据有问题
                            }
                        }
                    } else if ("=".equals(String.valueOf(c))) {
                        if (f2) {
                            list.add(buffer.toString());
                            buffer = new StringBuffer();
                            f2 = false;
                        }
                        tmp.append(c);
                        f1 = true;
                    } else {
                        tmp.append(c);
                    }

                    if (i == (s.length() - 1)) {
                        if (buffer.length() > 0 && tmp.length() > 0) {
                            list.add(buffer.toString());
                            list.add(tmp.toString());
                        } else if (buffer.length() > 0 && tmp.length() == 0) {
                            buffer.append(c);
                            list.add(buffer.toString());
                        } else if (buffer.length() == 0 && tmp.length() > 0) {
                            if ("&".equals(String.valueOf(c))) {
                                tmp.append(c);
                            }
                            list.add(tmp.toString());
                        }
                    }
                }
                if (list.size() > 0) {
                    JSONObject json = new JSONObject();
                    for (String l : list) {
                        String[] kv = l.split("=");
                        String v = "";
                        if (kv.length < 2 || StringUtils.isBlank(kv[1])) {
                            v = "";
                        } else {
                            v = kv[1];
                        }
                        json.put(kv[0], v);
                    }
                    json.put("log_transport_type", "retransmission");
                    return json.toJSONString();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
