package main

import (
	"database/sql"

	_ "modernc.org/sqlite"
)

var db *sql.DB

const schema = `
CREATE TABLE IF NOT EXISTS user (
    id         INTEGER PRIMARY KEY AUTOINCREMENT,
    uid        INTEGER UNIQUE,
    username   TEXT UNIQUE,
    password   BLOB,
    created_at INTEGER,
    last_login INTEGER,
    avatar     TEXT NOT NULL DEFAULT ''
);

CREATE TABLE IF NOT EXISTS session (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    uid         INTEGER,
    value       TEXT UNIQUE,
    created_at  INTEGER,
    expires     INTEGER,
    description TEXT
);

CREATE TABLE IF NOT EXISTS entry (
    id            INTEGER PRIMARY KEY AUTOINCREMENT,
    pid           INTEGER UNIQUE NOT NULL,
    uid           INTEGER NOT NULL,
    created_at    INTEGER NOT NULL,
    content       TEXT NOT NULL DEFAULT '',
    filepath      TEXT NOT NULL DEFAULT '',
    reply_to      INTEGER NOT NULL DEFAULT 0,
    reply_count   INTEGER NOT NULL DEFAULT 0,
    last_activity INTEGER NOT NULL DEFAULT 0,
    deleted       INTEGER NOT NULL DEFAULT 0
);

CREATE TABLE IF NOT EXISTS vote (
    id   INTEGER PRIMARY KEY AUTOINCREMENT,
    uid  INTEGER,
    pid  INTEGER,
    mode TEXT,
    UNIQUE(uid, pid)
);

-- Indizes für die häufigen Zugriffspfade; ohne sie werden Feed (ORDER BY
-- last_activity), Thread (WHERE reply_to) und Vote-Zähler (WHERE pid) mit
-- wachsender Tabelle zu Full-Table-Scans. username/session.value/vote(uid,pid)
-- sind über UNIQUE bereits indiziert.
CREATE INDEX IF NOT EXISTS idx_entry_last_activity ON entry(last_activity);
CREATE INDEX IF NOT EXISTS idx_entry_reply_to      ON entry(reply_to);
CREATE INDEX IF NOT EXISTS idx_entry_uid           ON entry(uid);
CREATE INDEX IF NOT EXISTS idx_vote_pid            ON vote(pid);
CREATE INDEX IF NOT EXISTS idx_session_uid         ON session(uid);
`

func initDB(dsn string) error {
	var err error
	// SQLite hat genau einen Schreiber: busy_timeout wartet bei Sperren, statt
	// sofort mit SQLITE_BUSY zu scheitern; WAL erlaubt parallele Leser.
	db, err = sql.Open("sqlite", dsn+"?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_pragma=foreign_keys(on)")
	if err != nil {
		return err
	}
	if err = db.Ping(); err != nil {
		return err
	}
	_, err = db.Exec(schema)
	return err
}
