#!/usr/bin/env python3
"""
Simple webhook server for Gitea auto-deployment.
Listens for push events and triggers deploy.sh
"""

import subprocess
import hmac
import hashlib
import json
import os
from http.server import HTTPServer, BaseHTTPRequestHandler
from datetime import datetime

# Configuration
WEBHOOK_SECRET = os.environ.get('WEBHOOK_SECRET', 'your-secret-here')
DEPLOY_SCRIPT = '/home/bini/shorts-maker/deploy.sh'
PORT = 9000
LOG_FILE = '/var/log/webhook-server.log'

def log(message):
    timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    log_line = f"[{timestamp}] {message}"
    print(log_line)
    try:
        with open(LOG_FILE, 'a') as f:
            f.write(log_line + '\n')
    except:
        pass

def verify_signature(payload, signature):
    """Verify Gitea webhook signature"""
    if not signature:
        return False
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

class WebhookHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        if self.path != '/webhook':
            self.send_response(404)
            self.end_headers()
            return

        content_length = int(self.headers.get('Content-Length', 0))
        payload = self.rfile.read(content_length)

        # Verify signature if secret is configured
        if WEBHOOK_SECRET != 'your-secret-here':
            signature = self.headers.get('X-Gitea-Signature')
            if not verify_signature(payload, signature):
                log("ERROR: Invalid webhook signature")
                self.send_response(403)
                self.end_headers()
                self.wfile.write(b'Invalid signature')
                return

        try:
            data = json.loads(payload)
            ref = data.get('ref', '')

            # Only deploy on push to main branch
            if ref == 'refs/heads/main':
                log(f"Received push to main from {data.get('pusher', {}).get('name', 'unknown')}")
                log(f"Commit: {data.get('after', 'unknown')[:8]}")

                # Run deploy script
                log("Starting deployment...")
                result = subprocess.run(
                    ['bash', DEPLOY_SCRIPT],
                    capture_output=True,
                    text=True,
                    timeout=600  # 10 minute timeout
                )

                if result.returncode == 0:
                    log("Deployment successful!")
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(b'Deployment successful')
                else:
                    log(f"Deployment failed: {result.stderr}")
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(f'Deployment failed: {result.stderr}'.encode())
            else:
                log(f"Ignoring push to {ref}")
                self.send_response(200)
                self.end_headers()
                self.wfile.write(b'Ignored (not main branch)')

        except json.JSONDecodeError:
            log("ERROR: Invalid JSON payload")
            self.send_response(400)
            self.end_headers()
            self.wfile.write(b'Invalid JSON')
        except subprocess.TimeoutExpired:
            log("ERROR: Deployment timed out")
            self.send_response(500)
            self.end_headers()
            self.wfile.write(b'Deployment timed out')
        except Exception as e:
            log(f"ERROR: {str(e)}")
            self.send_response(500)
            self.end_headers()
            self.wfile.write(f'Error: {str(e)}'.encode())

    def do_GET(self):
        if self.path == '/health':
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b'OK')
        else:
            self.send_response(404)
            self.end_headers()

    def log_message(self, format, *args):
        log(f"HTTP: {args[0]}")

if __name__ == '__main__':
    log(f"Starting webhook server on port {PORT}")
    server = HTTPServer(('0.0.0.0', PORT), WebhookHandler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        log("Shutting down webhook server")
        server.shutdown()
