# Copyright 2021 Max Planck Institute for Software Systems, and
# National University of Singapore
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

import fnmatch
import glob
import json
import re


def parse_iperf_run(data, skip=1, use=8):
    tp_pat = re.compile((
        r'\[ *\d*\] *([0-9\.]*)'
        r'- *([0-9\.]*) sec.*Bytes *([0-9\.]*) ([GM])bits.*'
    ))
    tps_time = {}
    for hn in fnmatch.filter(data['sims'].keys(), 'host.client.*'):
        sim = data['sims'][hn]
        for l in sim['stdout']:
            m = tp_pat.match(l)
            if not m:
                continue

            time = int(float(m.group(1)))
            if time < skip:
                continue
            if time >= skip + use:
                continue

            if time not in tps_time:
                tps_time[time] = []

            if m.group(4) == 'G':
                tps_time[time].append(float(m.group(3)))
            elif m.group(4) == 'M':
                m_tps = float(m.group(3)) / 1000
                tps_time[time].append(m_tps)

    tps = []
    for t in sorted(tps_time.keys()):
        x = sum(tps_time[t])
        tps.append(x)

    if len(tps) == 0:
        return None
    return sum(tps) / len(tps)


def parse_iperf(basename, skip=1, use=8):
    runs = []
    for path in glob.glob(basename + '-*.json'):
        if path == basename + '-0.json':
            # skip checkpoints
            continue

        with open(path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        result = parse_iperf_run(data, skip, use)
        if result is not None:
            runs.append(result)

    if not runs:
        return {'avg': None, 'min': None, 'max': None}
    else:
        return {
            'avg': sum(runs) / len(runs), 'min': min(runs), 'max': max(runs)
        }
    result = {}
