#!/usr/bin/python3
import argparse
import logging
import sys
from urllib.parse import urljoin, urlencode
import requests

log = logging.getLogger("redmine-remind")

DEFAULT_REDMINE_URL = "https://redmine.tails.boum.org/code/"
DEFAULT_QUERY_IDS = "318,319"


class Fail(Exception):
    pass


class Redmine:
    def __init__(self, server, api_key):
        self.server = server
        self.api_key = api_key

    def query(self, api, **kw):
        url = urljoin(self.server, api)
        if kw:
            url += "?" + urlencode(kw)
        log.info("Querying %s", url)
        res = requests.get(url, headers={
            "X-Redmine-API-Key": self.api_key
        })
        res.raise_for_status()
        return res.json()

    def whoami(self):
        return self.query("users/current.json")

    def get_user(self, user_id):
        return self.query(f"users/{user_id}.json")


def main():
    parser = argparse.ArgumentParser(description="Fetch reminder information from open redmine issyes")
    parser.add_argument("--verbose", "-v", action="store_true", help="verbose output")
    parser.add_argument("--debug", action="store_true", help="debug output")
    parser.add_argument("--api-key", action="store", required=True,
                        help="Redmine API key; use @file to read it from a file (required)")
    parser.add_argument("--server", action="store", default=DEFAULT_REDMINE_URL,
                        help="Redmine URL. Default: " + DEFAULT_REDMINE_URL)
    parser.add_argument("--query-ids", action="store", default=DEFAULT_QUERY_IDS,
                        help="IDs of queries to run. Default: " + DEFAULT_QUERY_IDS)
    parser.add_argument("--one-line", action="store_true",
                        help="Print output names all in one line, space separated")
    parser.add_argument("--print0", action="store_true",
                        help="Print output names with the null character instead of newline")

    args = parser.parse_args()

    log_format = "%(levelname)s %(message)s"
    level = logging.WARN
    if args.debug:
        level = logging.DEBUG
    elif args.verbose:
        level = logging.INFO
    logging.basicConfig(level=level, stream=sys.stderr, format=log_format)

    # Read API key
    api_key = args.api_key
    if api_key.startswith("@"):
        with open(api_key[1:], "rt") as fd:
            api_key = fd.read().strip()

    query_ids = args.query_ids.split(",")

    # Fetch issues
    redmine = Redmine(args.server, api_key)
    names = set()
    for query_id in query_ids:
        res = redmine.query("issues.json", query_id=query_id, project_id="tails")
        for issue in res["issues"]:
            assigned_to = issue.get("assigned_to")
            if assigned_to is None:
                continue
            names.add(assigned_to["name"])

    if args.one_line:
        print(" ".join(sorted(names)))
    elif args.print0:
        for name in sorted(names):
            print(name, end='\0')
    else:
        for name in sorted(names):
            print(name)


if __name__ == "__main__":
    try:
        main()
    except Fail as e:
        print(e, file=sys.stderr)
        sys.exit(1)
    except Exception:
        log.exception("uncaught exception")
