#!/usr/bin/env python3
"""Total time tagged language:spanish in Traggo, as decimal hours."""

import json
import subprocess
import sys
import urllib.request
from collections import defaultdict
from datetime import datetime, timezone

URL = "https://time.rcjohnstone.com/graphql"
USER = "connor"


def gql(query, cookie=None):
    req = urllib.request.Request(
        URL,
        data=json.dumps({"query": query}).encode(),
        headers={"Content-Type": "application/json"},
    )
    if cookie:
        req.add_header("Cookie", f"traggo={cookie}")
    body = json.load(urllib.request.urlopen(req))
    if body.get("errors"):
        sys.exit(f"traggo: {body['errors'][0]['message']}")
    return body["data"]


def login():
    pw = subprocess.run(
        ["rbw", "get", "Traggo"], capture_output=True, text=True, check=True
    ).stdout.strip()
    data = gql(
        'mutation{login(username:"%s",pass:%s,deviceName:"spanish-time",'
        "type:LongExpiry,cookie:false){token}}" % (USER, json.dumps(pw))
    )
    return data["login"]["token"]


def spans(token):
    offset, start_id = 0, None
    while True:
        cur = f"offset:{offset},pageSize:200"
        if start_id is not None:
            cur += f",startId:{start_id}"
        data = gql(
            '{timeSpans(fromInclusive:"2000-01-01T00:00:00Z",'
            'toInclusive:"2100-01-01T00:00:00Z",cursor:{%s})'
            "{cursor{hasMore offset startId} timeSpans{start end tags{key value}}}}"
            % cur,
            token,
        )["timeSpans"]
        yield from data["timeSpans"]
        if not data["cursor"]["hasMore"]:
            return
        offset, start_id = data["cursor"]["offset"], data["cursor"]["startId"]


def main():
    by_mode = defaultdict(float)
    for span in spans(login()):
        tags = {t["key"]: t["value"] for t in span["tags"]}
        if tags.get("language") != "spanish":
            continue
        start = datetime.fromisoformat(span["start"])
        end = (
            datetime.fromisoformat(span["end"])
            if span["end"]
            else datetime.now(timezone.utc)
        )
        by_mode[tags.get("mode", "untagged")] += (end - start).total_seconds() / 3600

    if "--by-mode" in sys.argv:
        for mode, hours in sorted(by_mode.items(), key=lambda kv: -kv[1]):
            print(f"{mode:12s} {hours:8.2f}")
    print(f"{sum(by_mode.values()):.2f}")


if __name__ == "__main__":
    main()
