"""Behind your public HTTPS reverse proxy. No event body or secret is logged."""
import os
import sqlite3
from http.server import BaseHTTPRequestHandler, HTTPServer
from docoki_sdk import verify_webhook, WebhookVerificationError


def accept(connection, event):
    connection.execute("BEGIN IMMEDIATE")
    try:
        inserted = connection.execute("INSERT OR IGNORE INTO receipts VALUES(?,?)", (event["event_id"], event["job_id"])).rowcount
        if inserted:
            connection.execute("UPDATE effects SET count=count+1 WHERE id=1")
        connection.commit()
        return bool(inserted)
    except Exception:
        connection.rollback()
        raise


def open_receipts(file):
    connection = sqlite3.connect(file)
    connection.executescript("CREATE TABLE IF NOT EXISTS receipts(event_id TEXT PRIMARY KEY, job_id TEXT NOT NULL); CREATE TABLE IF NOT EXISTS effects(id INTEGER PRIMARY KEY CHECK(id=1), count INTEGER NOT NULL); INSERT OR IGNORE INTO effects VALUES(1,0);")
    return connection


def main():
    secret, workspace = os.environ.get("DOCOKI_WEBHOOK_SECRET", ""), os.environ.get("DOCOKI_WORKSPACE_ID", "")
    if not secret or not workspace:
        raise RuntimeError("Configurer DOCOKI_WEBHOOK_SECRET et DOCOKI_WORKSPACE_ID.")
    os.umask(0o077)
    connection = open_receipts(os.environ.get("DOCOKI_RECEIPTS_DB", "docoki-receipts.sqlite"))

    class Handler(BaseHTTPRequestHandler):
        def log_message(self, *_):
            pass

        def do_POST(self):
            if self.path != "/webhook":
                self.send_error(404)
                return
            try:
                length = int(self.headers.get("Content-Length", "0"))
                if length < 1 or length > 16384 or self.headers.get("Transfer-Encoding"):
                    self.send_response(413)
                    self.end_headers()
                    return
                raw = self.rfile.read(length)
                event = verify_webhook(raw, self.headers.get("Docoki-Signature", ""), self.headers.get("Docoki-Event-Id", ""), secret, workspace_id=workspace)
                accept(connection, event)
                self.send_response(204)
            except WebhookVerificationError:
                self.send_response(401)
            except Exception:
                self.send_response(503)
            self.end_headers()

    print("Récepteur local prêt sur 127.0.0.1:9099 ; publier derrière votre terminaison HTTPS publique.")
    HTTPServer(("127.0.0.1", 9099), Handler).serve_forever()


if __name__ == "__main__":
    main()
