#!/usr/bin/env python3
"""Erzeugt/erneuert die Bootstrap-Lizenz DIESES Lizenzservers selbst.

Läuft rein lokal (kein Netzwerk, kein externer Super-Master) -- der Master
prüft seine eigene Lizenz über denselben license_active()-Mechanismus wie
Kundeninstanzen (siehe app.py), nur ohne Heartbeat-Ziel: dieses Skript
setzt den Aktivierungsstatus direkt in der Datenbank, da es keine höhere
Instanz gibt, die eine Aktivierung bestätigen könnte.

Nutzt denselben Master-Signaturschlüssel, den der Server auch zum
Ausstellen von Kundenlizenzen verwendet (wird beim ersten Aufruf
automatisch erzeugt, falls noch nicht vorhanden) -- WICHTIG: dieser
Schlüssel wird beim erneuten Aufruf (Verlängerung) wiederverwendet, nie
neu erzeugt, siehe _load_or_create_master_signing_key() weiter unten und
die identische Funktion in app.py: ein Schlüsselwechsel würde die
Offline-Verifikation künftiger Aktivierungs-/Heartbeat-Antworten für ALLE
bereits an Kunden ausgegebenen Lizenzen brechen.

Aufruf:
    python3 create_master_license.py [--days 730] [--name "Firma XY"]

Erneuerung (z.B. kurz vor Ablauf): einfach erneut aufrufen -- überschreibt
die bestehende Bootstrap-Lizenz, der Signaturschlüssel bleibt unverändert.
"""
import argparse
import json
import os
import sqlite3
import sys

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import licensing

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
MASTER_SIGNING_KEY_PATH = os.environ.get("TESM_LICENSE_MASTER_KEY", os.path.join(BASE_DIR, "master_signing_key.json"))
LICENSE_PATH = os.environ.get("TESM_LICENSE_PATH", os.path.join(BASE_DIR, "license.json"))
DB_PATH = os.environ.get("TESM_LICENSE_DB_PATH", os.path.join(BASE_DIR, "sqlite.db"))


def _load_or_create_master_signing_key():
    try:
        with open(MASTER_SIGNING_KEY_PATH, "r", encoding="utf-8") as f:
            data = json.load(f)
        return data["private"], data["public"], False
    except (OSError, ValueError, KeyError):
        priv, pub = licensing.generate_keypair()
        with open(MASTER_SIGNING_KEY_PATH, "w", encoding="utf-8") as f:
            json.dump({"private": priv, "public": pub}, f)
        try:
            os.chmod(MASTER_SIGNING_KEY_PATH, 0o600)
        except OSError:
            pass
        return priv, pub, True


def main():
    parser = argparse.ArgumentParser(description="Erzeugt/erneuert die Bootstrap-Lizenz dieses Lizenzservers.")
    parser.add_argument("--days", type=int, default=730, help="Gültigkeitsdauer in Tagen (Standard: 730 = 2 Jahre)")
    parser.add_argument("--name", default="Lizenzserver (Eigenbetrieb)", help="Anzeigename in der Lizenzdatei")
    args = parser.parse_args()

    master_priv, master_pub, created = _load_or_create_master_signing_key()
    if created:
        print(f"Neuer Master-Signaturschlüssel erzeugt: {MASTER_SIGNING_KEY_PATH}")
    else:
        print(f"Bestehenden Master-Signaturschlüssel wiederverwendet: {MASTER_SIGNING_KEY_PATH}")

    license_file, _pub = licensing.issue_license(
        customer={"name": args.name, "contact_email": ""},
        license_type="enterprise",
        modules=[],
        valid_days=args.days,
        master_private_key_b64=master_priv,
        master_public_key_b64=master_pub,
        master_endpoint="",
        vendor={"name": "", "phone": "", "email": "", "address": "", "logo_base64": ""},
    )
    with open(LICENSE_PATH, "w", encoding="utf-8") as f:
        json.dump(license_file, f, indent=2)
    try:
        os.chmod(LICENSE_PATH, 0o600)
    except OSError:
        pass
    print(f"Bootstrap-Lizenz geschrieben: {LICENSE_PATH} (gültig {args.days} Tage, bis {license_file['expires_at']})")

    if os.path.exists(DB_PATH):
        conn = sqlite3.connect(DB_PATH)
        conn.execute(
            "INSERT INTO settings (key, value) VALUES ('license_activation_status', 'active') "
            "ON CONFLICT(key) DO UPDATE SET value=excluded.value"
        )
        conn.commit()
        conn.close()
        print("Aktivierungsstatus in der Datenbank auf 'active' gesetzt.")
    else:
        print(
            f"WARNUNG: Datenbank {DB_PATH} nicht gefunden -- bitte zuerst create_db.py ausführen, "
            "dann dieses Skript erneut aufrufen, damit der Aktivierungsstatus gesetzt werden kann."
        )

    print("Fertig -- Dienst neu starten (oder warten, bis der Prozess die Lizenz beim nächsten Zugriff neu lädt).")


if __name__ == "__main__":
    main()
