#!/usr/bin/env python3
"""All-time kill counter (bots and humans).
  ./kills          show the scoreboard (and save the tally)
Counts the " killed " lines in hlds/cstrike/logs. Per-log counts are kept in kills-tally.json,
so the totals survive scripts/backup.sh deleting logs older than 30 days (it runs this first)."""
import collections, json, os, re

D = os.path.dirname(os.path.abspath(__file__))
LOGS = os.path.join(D, "hlds", "cstrike", "logs")
STATE = os.path.join(D, "kills-tally.json")
KILL = re.compile(r'^L (\d\d/\d\d/\d{4}) - [\d:]+: "(.+?)<\d+><[^>]*><[^>]*>" killed '
                  r'".+?<\d+><[^>]*><[^>]*>" with "([^"]+)"')

try:
    st = json.load(open(STATE))
except (OSError, ValueError):
    st = {"files": {}}
for f in sorted(os.listdir(LOGS)) if os.path.isdir(LOGS) else []:
    if not f.endswith(".log"):
        continue
    n, who, wpn, days = 0, collections.Counter(), collections.Counter(), set()
    for line in open(os.path.join(LOGS, f), encoding="utf-8", errors="replace"):
        m = KILL.match(line)
        if m:
            n += 1; days.add(m[1]); who[m[2]] += 1; wpn[m[3]] += 1
    if n or f not in st["files"]:
        st["files"][f] = {"kills": n, "who": who, "wpn": wpn, "days": sorted(days)}
tmp = STATE + ".tmp"
json.dump(st, open(tmp, "w"))
os.replace(tmp, STATE)

total, who, wpn, days = 0, collections.Counter(), collections.Counter(), set()
for v in st["files"].values():
    total += v["kills"]; who.update(v["who"]); wpn.update(v["wpn"]); days.update(v["days"])
print(f"\n  ALL-TIME KILLS: {total:,}   ({len(days)} days of carnage, {len(st['files'])} maps played)\n")
print("  top fraggers:")
for i, (n, k) in enumerate(who.most_common(5), 1):
    print(f"   {i}. {n:<18} {k:,}")
print("\n  weapons of choice:")
for n, k in wpn.most_common(5):
    print(f"   {n:<18} {k:,}")
print()
