# retoor <retoor@molodetz.nl>

from __future__ import annotations

import os
import re
import time
import xmlrpc.client
from typing import Iterator

from client import DevPlace

URL = os.environ.get("DEVPLACE_URL", "https://devplace.net")
API_KEY = os.environ.get("DEVPLACE_API_KEY", "YOUR_API_KEY")
POLL_SECONDS = int(os.environ.get("DEVPLACE_POLL_SECONDS", "30"))
REPLY = os.environ.get(
    "DEVPLACE_REPLY",
    "Thanks for the mention! This is an automated reply via the XML-RPC bridge.",
)

POST_SLUG = re.compile(r"/posts/([^/#?]+)")


def unread_mentions(dp: DevPlace) -> Iterator[dict]:
    result = dp.call("notifications.list")
    for group in result.get("notification_groups", []):
        for entry in group.get("entries", []):
            note = entry["notification"]
            if note.get("type") == "mention" and not note.get("read"):
                yield note


def reply_to_mention(dp: DevPlace, note: dict) -> bool:
    match = POST_SLUG.search(note.get("target_url") or "")
    if not match:
        return False
    detail = dp.call("posts.detail", post_slug=match.group(1))
    dp.call(
        "comments.create",
        content=REPLY,
        target_uid=detail["post"]["uid"],
        target_type="post",
    )
    return True


def run() -> None:
    dp = DevPlace(URL, api_key=API_KEY)
    print(f"Mention bot started; polling {URL} every {POLL_SECONDS}s.")
    while True:
        try:
            for note in unread_mentions(dp):
                try:
                    if reply_to_mention(dp, note):
                        print("Replied to:", note.get("message"))
                except xmlrpc.client.Fault as fault:
                    print("Could not reply:", fault.faultCode, fault.faultString)
                finally:
                    dp.call("notifications.mark.read", notification_uid=note["uid"])
        except xmlrpc.client.Fault as fault:
            print("Poll error:", fault.faultCode, fault.faultString)
        except OSError as error:
            print("Network error, retrying:", error)
        time.sleep(POLL_SECONDS)


if __name__ == "__main__":
    run()
