#!/usr/bin/python3

import argparse
import json
import libvoters.acceptable as acceptable
import os
import re
from collections import defaultdict
from libvoters.time import timestamp, TimeOfDay
from typing import Any, Dict


class subcmd:
    def __init__(self, parser: argparse._SubParsersAction) -> None:
        p = parser.add_parser(
            "analyze-commits", help="Determine points for commits"
        )

        p.add_argument(
            "--before",
            "-b",
            help="Before timestamp (YYYY-MM-DD)",
            required=True,
        )
        p.add_argument(
            "--after",
            "-a",
            help="After timestamp (YYYY-MM-DD)",
            required=True,
        )

        p.set_defaults(cmd=self)

    def run(self, args: argparse.Namespace) -> int:
        before = timestamp(args.before, TimeOfDay.AM)
        after = timestamp(args.after, TimeOfDay.PM)

        changes_per_user: Dict[str, list[int]] = defaultdict(list)

        for f in sorted(os.listdir(args.dir)):
            path = os.path.join(args.dir, f)
            if not os.path.isfile(path):
                continue

            if not re.match("[0-9]*\.json", f):
                continue

            with open(path, "r") as file:
                data = json.load(file)

            if data["status"] != "MERGED":
                continue

            merged_at = 0
            for c in data["comments"]:
                if "timestamp" not in c:
                    continue
                if "message" in c and re.match(
                    "Change has been successfully .*", c["message"]
                ):
                    merged_at = c["timestamp"]

            if merged_at == 0:
                raise RuntimeError(f"Missing merge timestamp on {f}")

            if merged_at > before or merged_at < after:
                continue

            project = data["project"]
            id_number = data["number"]
            user = data["owner"]["username"]

            if not acceptable.project(project):
                print("Rejected project:", project, id_number)
                continue

            changes = 0
            touched_files = []
            for file_data in sorted(
                data["patchSets"], key=lambda x: x["number"]
            )[-1][
                "files"
            ]:  # type: Dict[str, Any]
                if not acceptable.file(project, file_data["file"]):
                    continue
                changes += int(file_data["insertions"]) + abs(
                    int(file_data["deletions"])
                )
                touched_files.append(file_data["file"])

            if changes < 10:
                print("Rejected for limited changes:", project, id_number)
                continue

            print(project, id_number, user)
            for f in touched_files:
                print(f"    {f}")

            changes_per_user[user].append(id_number)

        with open(os.path.join(args.dir, "commits.json"), "w") as outfile:
            outfile.write(json.dumps(changes_per_user, indent=4))

        return 0
