#!/usr/bin/env python3
"""Initialisiert die SQLite-Datenbank für den TESM-Lizenzserver (Master).

WICHTIG: Wer hier eine neue Tabelle oder Spalte hinzufügt, muss auch die
Datei SCHEMA_VERSION (daneben, im selben Verzeichnis) um 1 erhöhen.
update.sh vergleicht diese Zahl zwischen der aktuell installierten und der
neuen Version, um zu entscheiden, ob ein Update in-place laufen darf
(bestehende Datenbank bleibt erhalten) oder eine frische Installation
nötig ist (Datenbank wird beiseitegesichert). Ein vergessenes Hochzählen
würde dazu führen, dass ein Host mit altem Schema faelschlich per
In-Place-Update aktualisiert wird, statt frisch installiert zu werden --
_ensure_schema() faengt die meisten Faelle zwar zur Laufzeit ab, ist aber
kein Ersatz fuer eine korrekte Versionsnummer hier.

Gegenüber TESM entfernt: credentials/switches/devices/dhcp_*/
ldap_fileshare_mappings (kein Geräte-/DHCP-/Fileshare-Management auf dem
Lizenzserver). Neu: license_customers/licenses (Kern des Lizenzservers,
siehe licensing.py für das zugehörige Kryptographie-/Protokollformat)."""
import os
import sqlite3

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DB_PATH = os.environ.get("TESM_LICENSE_DB_PATH", os.path.join(BASE_DIR, "sqlite.db"))

conn = sqlite3.connect(DB_PATH)
c = conn.cursor()

c.execute("""
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    username TEXT UNIQUE NOT NULL,
    password TEXT NOT NULL,
    is_admin INTEGER DEFAULT 0,
    first_name TEXT,
    last_name TEXT,
    avatar_filename TEXT,
    auth_source TEXT NOT NULL DEFAULT 'local',
    email TEXT,
    is_locked INTEGER NOT NULL DEFAULT 0,
    deleted_at TEXT
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS groups (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT UNIQUE NOT NULL,
    is_default INTEGER DEFAULT 0,
    is_system INTEGER DEFAULT 0,
    deleted_at TEXT
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS group_permissions (
    group_id INTEGER NOT NULL,
    permission TEXT NOT NULL,
    PRIMARY KEY (group_id, permission),
    FOREIGN KEY (group_id) REFERENCES groups(id)
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS user_groups (
    user_id INTEGER NOT NULL,
    group_id INTEGER NOT NULL,
    PRIMARY KEY (user_id, group_id),
    FOREIGN KEY (user_id) REFERENCES users(id),
    FOREIGN KEY (group_id) REFERENCES groups(id)
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS settings (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS service_accounts (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    purpose TEXT UNIQUE NOT NULL,
    username TEXT NOT NULL,
    password TEXT NOT NULL
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS ldap_group_mappings (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ad_group_dn TEXT UNIQUE NOT NULL,
    ad_group_name TEXT NOT NULL,
    app_group_id INTEGER NOT NULL,
    FOREIGN KEY (app_group_id) REFERENCES groups(id)
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS audit_log (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    ts TEXT NOT NULL,
    username TEXT NOT NULL,
    action TEXT NOT NULL,
    target TEXT,
    details TEXT
);
""")

# --- Kern des Lizenzservers ---------------------------------------------

c.execute("""
CREATE TABLE IF NOT EXISTS license_customers (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    contact_email TEXT,
    contact_phone TEXT,
    notes TEXT,
    created_at TEXT NOT NULL
);
""")

c.execute("""
CREATE TABLE IF NOT EXISTS licenses (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    license_id TEXT UNIQUE NOT NULL,
    customer_id INTEGER NOT NULL,
    type TEXT NOT NULL,
    modules TEXT NOT NULL DEFAULT '[]',
    issued_at TEXT NOT NULL,
    expires_at TEXT NOT NULL,
    license_pubkey TEXT NOT NULL,
    license_file_json TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'issued',
    fingerprint TEXT,
    activated_at TEXT,
    deactivated_at TEXT,
    last_heartbeat_at TEXT,
    revoked_at TEXT,
    role TEXT NOT NULL DEFAULT 'customer',
    created_by TEXT,
    created_at TEXT NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES license_customers(id)
);
""")

c.execute("INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)", ("interval", "5"))

cur = c.execute("INSERT OR IGNORE INTO groups (name, is_default, is_system) VALUES (?, 1, 1)", ("Benutzer",))
if cur.rowcount > 0:
    default_group_id = cur.lastrowid
    c.executemany(
        "INSERT OR IGNORE INTO group_permissions (group_id, permission) VALUES (?, ?)",
        [
            (default_group_id, "logs_group.view"),
            (default_group_id, "logs_live.view"),
        ],
    )

conn.commit()
conn.close()
print(f"Datenbank '{DB_PATH}' wurde initialisiert inklusive Settings.")
