#!/usr/bin/python3

import argparse
import hmac
import json
import os
import pprint
import random
import socket
import subprocess
import time
import re

import requests

ap = argparse.ArgumentParser()
ap.add_argument("hostname")
args = ap.parse_args()

# It's a bit weird that this works.
myhostname = socket.gethostbyaddr(socket.gethostname())[0]

now = time.time()
p = subprocess.run(["/bin/ping", "-c", "20", "-i", "0.2", "-n", args.hostname], capture_output=True, text=True)
report0 = []
for ln in p.stdout.split("\n")[:-1]:
    m = re.match(r"(\d+) packets transmitted, (\d+) received, (\d+)% packet loss", ln)
    if m:
        report0.append({ "measure": "ping_transmitted", "unit": "packets", "value": int(m.group(1)) })
        report0.append({ "measure": "ping_received", "unit": "packets", "value": int(m.group(2)) })
        report0.append({ "measure": "ping_loss", "unit": "%", "value": int(m.group(3)) })
        continue
    m = re.match(r"rtt min/avg/max/mdev = ([0-9.]+)/([0-9.]+)/([0-9.]+)/([0-9.]+) ms", ln)
    if m:
        report0.append({ "measure": "ping_min_rtt", "unit": "s", "value": float(m.group(1)) / 1000 })
        report0.append({ "measure": "ping_avg_rtt", "unit": "s", "value": float(m.group(2)) / 1000 })
        report0.append({ "measure": "ping_max_rtt", "unit": "s", "value": float(m.group(3)) / 1000 })
        report0.append({ "measure": "ping_mdev_rtt", "unit": "s", "value": float(m.group(4)) / 1000 })
        continue

if len(report0) != 7:
    print("Partial results:", report0)

report = [
    {
        "description": {
            "hostname": args.hostname,
            "measure": r["measure"],
            "unit": r["unit"]
        },
        "data": [
            [now, r["value"]]
        ]
    }
    for r in report0
]

for dir in (".", os.environ["HOME"] + "/.config/ltsdb", "/etc/ltsdb"):
    try:
        with open(dir + "/config.json") as fh:
            client_config = json.load(fh)
        baseurl = client_config["server"]
        break
    except FileNotFoundError:
        pass
while True:
    for r in report:
        node = myhostname
        timestamp = time.time()
        msg = (node + " " + str(timestamp)).encode("UTF-8")
        digest = hmac.new(client_config["key"].encode("UTF-8"), msg, "SHA256").hexdigest()
        r["auth"] = {
            "node": node,
            "timestamp": timestamp,
            "hmac": digest,
        }
    #pprint.pp(report)
    r = requests.post(baseurl + "report", json=report)
    print(r)
    if r.status_code == 200:
        exit(0)
    elif r.status_code == 409:
        time.sleep(0.5 + random.random())
        continue
    else:
        exit(1)