#!/usr/bin/env python3
"""Gitea to ntfy Webhook Bridge - Translates Gitea events to ntfy notifications"""

import os
import sys
import json
import urllib.request
from http.server import HTTPServer, BaseHTTPRequestHandler

# Force unbuffered output
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', buffering=1)
sys.stderr = os.fdopen(sys.stderr.fileno(), 'w', buffering=1)

NTFY_URL = os.environ.get("NTFY_URL", "https://ntfy.vish.gg")
NTFY_TOPIC = os.environ.get("NTFY_TOPIC", "homelab-alerts")

class WebhookHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        """Health check endpoint"""
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()
        self.wfile.write(b"Gitea-ntfy bridge OK\n")
        print(f"Health check from {self.client_address[0]}", flush=True)

    def do_POST(self):
        content_length = int(self.headers.get("Content-Length", 0))
        body = self.rfile.read(content_length)

        try:
            data = json.loads(body) if body else {}
            event_type = self.headers.get("X-Gitea-Event", "unknown")

            print(f"Received {event_type} event from {self.client_address[0]}", flush=True)

            title, message, tags, priority = self.format_message(event_type, data)

            if title and message:
                print(f"Sending notification: {title}", flush=True)
                self.send_ntfy(title, message, tags, priority)
                self.send_response(200)
            else:
                print(f"Ignoring event type: {event_type}", flush=True)
                self.send_response(204)  # No content to send
        except Exception as e:
            print(f"Error processing webhook: {e}", flush=True)
            self.send_response(500)

        self.end_headers()

    def format_message(self, event_type, data):
        """Format Gitea event into ntfy message"""
        repo = data.get("repository", {}).get("full_name", "unknown")
        sender = data.get("sender", {}).get("login", "unknown")

        title = None
        message = None
        tags = "git"
        priority = "default"

        if event_type == "push":
            commits = data.get("commits", [])
            branch = data.get("ref", "").replace("refs/heads/", "")
            count = len(commits)
            title = f"Push to {repo}"
            message = f"{sender} pushed {count} commit(s) to {branch}"
            if commits:
                message += f"\n\n* {commits[0].get('message', '').split(chr(10))[0]}"
                if count > 1:
                    message += f"\n* ... and {count - 1} more"
            tags = "package"

        elif event_type == "pull_request":
            action = data.get("action", "")
            pr = data.get("pull_request", {})
            pr_title = pr.get("title", "")
            pr_num = pr.get("number", "")
            title = f"PR #{pr_num} {action}"
            message = f"{repo}: {pr_title}\nBy: {sender}"
            tags = "twisted_rightwards_arrows"
            if action == "opened":
                priority = "high"

        elif event_type == "issues":
            action = data.get("action", "")
            issue = data.get("issue", {})
            issue_title = issue.get("title", "")
            issue_num = issue.get("number", "")
            title = f"Issue #{issue_num} {action}"
            message = f"{repo}: {issue_title}\nBy: {sender}"
            tags = "clipboard"

        elif event_type == "release":
            action = data.get("action", "")
            release = data.get("release", {})
            tag = release.get("tag_name", "")
            title = f"Release {tag}"
            message = f"{repo}: New release {action}\n{release.get('name', tag)}"
            tags = "rocket"
            priority = "high"

        elif event_type == "create":
            ref_type = data.get("ref_type", "")
            ref = data.get("ref", "")
            title = f"New {ref_type}: {ref}"
            message = f"{repo}\nCreated by: {sender}"
            tags = "sparkles"

        elif event_type == "delete":
            ref_type = data.get("ref_type", "")
            ref = data.get("ref", "")
            title = f"Deleted {ref_type}: {ref}"
            message = f"{repo}\nDeleted by: {sender}"
            tags = "wastebasket"

        return title, message, tags, priority

    def send_ntfy(self, title, message, tags="git", priority="default"):
        """Send notification to ntfy"""
        url = f"{NTFY_URL}/{NTFY_TOPIC}"
        headers = {
            "Title": title,
            "Tags": tags,
            "Priority": priority,
        }

        req = urllib.request.Request(url, data=message.encode('utf-8'), headers=headers, method="POST")
        try:
            with urllib.request.urlopen(req, timeout=10) as resp:
                print(f"Sent: {title} -> {resp.status}")
        except Exception as e:
            print(f"Failed to send ntfy: {e}")

    def log_message(self, format, *args):
        print(f"[{self.log_date_time_string()}] {format % args}")

if __name__ == "__main__":
    server = HTTPServer(("0.0.0.0", 8095), WebhookHandler)
    print(f"Gitea-ntfy bridge running on :8095 -> {NTFY_URL}/{NTFY_TOPIC}")
    server.serve_forever()
