#!/usr/bin/python3
# coding=utf-8
import sys
import json
import operator

LOSTRETRANSMIT = 0
RTORETRANSMIT = 0
FASTRETRANSMIT = 0
SYNRETRANSMIT = 0
FAILEDRETRANSMIT = 0
TCPLOSSPROBES = 0


def delta_map(pre, now):
    delta = {}
    for k, v in pre.items():
        delta[k] = now[k] - v
    return delta


def retran_stat(res):
    global LOSTRETRANSMIT
    global RTORETRANSMIT
    global FASTRETRANSMIT
    global SYNRETRANSMIT
    global FAILEDRETRANSMIT
    global TCPLOSSPROBES

    netstat = delta_map(res[0]['netstat'], res[-1]['netstat'])
    LOSTRETRANSMIT = netstat['TcpExt::TCPLostRetransmit']
    RTORETRANSMIT = netstat['TcpExt::TCPSlowStartRetrans']
    FASTRETRANSMIT = netstat['TcpExt::TCPFastRetrans']
    SYNRETRANSMIT = netstat['TcpExt::TCPSynRetrans']
    FAILEDRETRANSMIT = netstat['TcpExt::TCPRetransFail']
    TCPLOSSPROBES = netstat['TcpExt::TCPLossProbes']


def retran_result(res):
    global LOSTRETRANSMIT
    global RTORETRANSMIT
    global FASTRETRANSMIT
    global SYNRETRANSMIT
    global FAILEDRETRANSMIT
    global TCPLOSSPROBES

    postprocess_result = {
        "code": 0,
        "err_msg": "",
        "result": {}
    }
    if len(res) == 0:
        postprocess_result["code"] = 1
        postprocess_result["err_msg"] = f"Diagnosis failed:\n{raw}"
        print(json.dumps(postprocess_result, indent=4))
        return

    retran_stat(res)
    newretran = {}
    newretran["retranList"] = {}
    newretran["retranList"]['data'] = []
    retran_cnt = 0

    sport_dis = {}
    dport_dis = {}
    sip_dis = {}
    dip_dis = {}

    retran_summary = {
        "SynRetran": 0,
        "SlowStartRetran": 0,
        "RtoRetran": 0,
        "FastRetran": 0,
        "TLP": 0,
        "FailedRetran": FAILEDRETRANSMIT,
        "Other": 0,
    }

    for item in res[1:-1]:
        sport = item['sport']
        dport = item['dport']
        sip = item['sip']
        dip = item['dip']
        rtype = item["retran_type"]

        retran_cnt += 1
        newretran["retranList"]["data"].append({
            "id": str(retran_cnt), "source": sip + ':' + str(sport), "destination": dip + ':' + str(dport), "tcpState": item["tcp_state"],
            "caState": item["ca_state"], "type": rtype
        })

        sport_dis[sport] = sport_dis.get(sport, 0) + 1
        dport_dis[dport] = dport_dis.get(dport, 0) + 1
        sip_dis[sip] = sip_dis.get(sip, 0) + 1
        dip_dis[dip] = dip_dis.get(dip, 0) + 1

        retran_summary[rtype] += 1

    newretran["retranSummary"] = {}
    newretran["retranSummary"]["data"] = [
        {"key": index, 'value': item}
        for index, item in retran_summary.items()
    ]

    top_sports = dict(
        sorted(sport_dis.items(), key=operator.itemgetter(1), reverse=True)[:5])
    top_dports = dict(
        sorted(dport_dis.items(), key=operator.itemgetter(1), reverse=True)[:5])
    top_sips = dict(
        sorted(sip_dis.items(), key=operator.itemgetter(1), reverse=True)[:5])
    top_dips = dict(
        sorted(dip_dis.items(), key=operator.itemgetter(1), reverse=True)[:5])

    newretran["sourcePortDistribution"] = {}
    newretran["sourcePortDistribution"]["data"] = [
        {"key": "port:" + str(index), 'value': item}
        for index, item in top_sports.items()]

    newretran["destPortDistribution"] = {}
    newretran["destPortDistribution"]["data"] = [
        {"key": "port:" + str(index), 'value': item}
        for index, item in top_dports.items()]

    newretran["sourceIpDistribution"] = {}
    newretran["sourceIpDistribution"]["data"] = [
        {"key": "ip:" + index, 'value': item}
        for index, item in top_sips.items()]

    newretran["destIpDistribution"] = {}
    newretran["destIpDistribution"]["data"] = [
        {"key": "ip:" + index, 'value': item}
        for index, item in top_dips.items()]

    newretran["summary"] = "diagnones result: total capture {} retransmits".format(
        retran_cnt)
    postprocess_result["result"] = newretran
    print(json.dumps(postprocess_result, ensure_ascii=False))


def extract_params():
    path, res, task_id = sys.argv[1], [], sys.argv[2]
    with open(path, 'r') as tmp:
        for line in tmp.readlines():
            obj = json.loads(line)
            res.append(obj)

    return res, task_id


if __name__ == "__main__":
    res, _ = extract_params()
    retran_result(res)
