"""
automatically labels issues referenced in merge requests with
specified labels.
"""

import os
import re
import logging

log = logging.getLogger(__name__)


title_regex = r"^(?:#|)(\d+)\s*"
word_regex = r"^#(\d+)$"
relation_keywords = [
    "related"
]
relation_distance = 2

state_label = {
    "closed": "In Progress",
    "opened": "Code-Review",
    "merged": "C-R Bestanden",
}

# Extra labels that the bot will check for before acting
act_labels = [
    "Sprint",
    "Testing",
    "TestingFailed",
]

async def merge_label_hook(event, gl, *args, **kwargs):
    title = event.object_attributes["title"]
    description = event.object_attributes["description"]
    state = event.object_attributes["state"]
    related_issues = []

    if title.lower().startswith("draft"):
        return

    match = re.search(title_regex, title)
    if match:
        related_issues.append(match.group(1))

    for line in description.split("\\n"):
        line = line.lower()
        line_list = line.split(" ")

        for keyword in relation_keywords:
            try:
                keyword_index = line_list.index(keyword)

                min_pos = keyword_index - relation_distance
                if min_pos < 0:
                    min_pos = 0

                max_pos = keyword_index + relation_distance
                if max_pos >= len(line_list):
                    max_pos = len(line_list)-1

                for word in line_list[min_pos:max_pos+1]:
                    match = re.search(word_regex, word)
                    if match:
                        related_issues.append(match.group(1))

            except ValueError:
                pass

    for issue in related_issues:
        if not issue: continue

        base_url = f"/projects/{event.project_id}/issues/{issue}"

        has_label = False
        issue_data = await gl.getitem(base_url)
        for label in issue_data["labels"]:
            if label in act_labels or state_label.values():
                has_label = True
                break

        if not has_label:
            log.debug(f"Issue #{issue} does not have a relevant label")
            continue

        delete_labels = act_labels + list(state_label.values())

        try:
            label = state_label[state]
            if label in delete_labels:
                delete_labels.remove(label)

            remove_labels = ",".join(delete_labels)

            await gl.put(base_url, data={
                "add_labels": label,
                "remove_labels": remove_labels,
            })

        except KeyError:
            log.exception("Unknown state")

def setup(bot) -> None:
    bot.register_merge_hook(merge_label_hook)
