-- ============================================================
-- AETHER CHAT — Veritabanı Şeması
-- BLOK 1.1 / schema.sql
--
-- Felsefe: Server sıfır mesaj saklar.
-- Sadece kimlik koordinasyonu için minimum veri.
-- Tüm TTL'ler 24 saat — sonra otomatik silinir.
-- ============================================================

CREATE DATABASE IF NOT EXISTS aether
  CHARACTER SET utf8mb4
  COLLATE utf8mb4_unicode_ci;

USE aether;

-- ────────────────────────────────────────────────────────────
-- 1. AKTİF OTURUMLAR
--    Sunucuda saklanan TEK kullanıcı verisi.
--    Telefon numarası asla düz metin saklanmaz — sadece hash.
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS active_sessions (
    phone_hash   VARCHAR(64)   NOT NULL,
    username     VARCHAR(50)   NOT NULL,
    display_name VARCHAR(100)  NOT NULL DEFAULT '',
    ip_address   VARCHAR(45)   NOT NULL,
    token_hash   VARCHAR(64)   NOT NULL,
    public_key   TEXT          NOT NULL,   -- X25519 pub key (key exchange)
    status       ENUM('online','away','offline') NOT NULL DEFAULT 'offline',
    last_seen    DATETIME      NOT NULL    DEFAULT CURRENT_TIMESTAMP,
    expires_at   DATETIME      NOT NULL,   -- 24 saat TTL
    created_at   DATETIME      NOT NULL    DEFAULT CURRENT_TIMESTAMP,

    PRIMARY KEY  (phone_hash),
    UNIQUE  KEY  uq_username    (username),
    INDEX        idx_token      (token_hash),
    INDEX        idx_status     (status),
    INDEX        idx_expires    (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ────────────────────────────────────────────────────────────
-- 2. GRUPLAR  (sadece meta — mesaj yok)
--    Üye listesi hash'i grupId'ye bağlı.
--    24 saat TTL — tüm üyeler yeniden giriş yapınca yenilenir.
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS chat_groups (
    group_id     CHAR(36)      NOT NULL,   -- UUID
    group_name   VARCHAR(100)  NOT NULL,
    creator_hash VARCHAR(64)   NOT NULL,   -- Kurucu phone_hash
    invite_code  VARCHAR(12)   NOT NULL,   -- Kısa davet kodu
    max_members  TINYINT       NOT NULL    DEFAULT 50,
    expires_at   DATETIME      NOT NULL,
    created_at   DATETIME      NOT NULL    DEFAULT CURRENT_TIMESTAMP,

    PRIMARY KEY  (group_id),
    UNIQUE  KEY  uq_invite      (invite_code),
    INDEX        idx_creator    (creator_hash),
    INDEX        idx_expires    (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ────────────────────────────────────────────────────────────
-- 3. GRUP ÜYELERİ
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS group_members (
    group_id     CHAR(36)      NOT NULL,
    phone_hash   VARCHAR(64)   NOT NULL,
    username     VARCHAR(50)   NOT NULL    DEFAULT '',
    role         ENUM('admin','member') NOT NULL DEFAULT 'member',
    joined_at    DATETIME      NOT NULL    DEFAULT CURRENT_TIMESTAMP,

    PRIMARY KEY  (group_id, phone_hash),
    INDEX        idx_phone      (phone_hash),
    INDEX        idx_group      (group_id),

    FOREIGN KEY  (group_id)
        REFERENCES chat_groups(group_id)
        ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ────────────────────────────────────────────────────────────
-- 4. SİNYAL KUYRUĞU  (WebRTC — sadece kısa süreli RAM yedek)
--    Hedef offline iken gelen call_offer / key_exchange
--    maksimum 60 saniye saklanır, sonra silinir.
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS signal_queue (
    id           BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    from_hash    VARCHAR(64)    NOT NULL,
    to_hash      VARCHAR(64)    NOT NULL,
    signal_type  VARCHAR(30)    NOT NULL,  -- key_exchange | call_offer | call_ice
    payload      MEDIUMTEXT     NOT NULL,  -- JSON şifreli payload
    expires_at   DATETIME       NOT NULL,  -- Maks 60 saniye
    created_at   DATETIME       NOT NULL   DEFAULT CURRENT_TIMESTAMP,

    PRIMARY KEY  (id),
    INDEX        idx_to_hash    (to_hash),
    INDEX        idx_expires    (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ────────────────────────────────────────────────────────────
-- 5. RATE LIMIT KAYITLARI  (IP başına istek sayacı)
--    Redis yoksa bu tablo kullanılır.
-- ────────────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS rate_limits (
    rl_key       VARCHAR(128)  NOT NULL,
    hit_count    SMALLINT      NOT NULL   DEFAULT 1,
    window_start DATETIME      NOT NULL   DEFAULT CURRENT_TIMESTAMP,
    expires_at   DATETIME      NOT NULL,

    PRIMARY KEY  (rl_key),
    INDEX        idx_expires   (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;


-- ────────────────────────────────────────────────────────────
-- 6. OTOMATİK TEMİZLEME EVENT'İ
--    Her saat çalışır — süresi dolmuş her şeyi siler.
-- ────────────────────────────────────────────────────────────
DELIMITER $$

DROP EVENT IF EXISTS aether_cleanup$$

CREATE EVENT aether_cleanup
    ON SCHEDULE EVERY 1 HOUR
    STARTS NOW()
    DO
    BEGIN
        -- Süresi dolmuş oturumları sil
        DELETE FROM active_sessions
        WHERE expires_at < NOW();

        -- Süresi dolmuş grupları sil (cascade ile üyeleri de)
        DELETE FROM chat_groups
        WHERE expires_at < NOW();

        -- Sinyal kuyruğunu temizle
        DELETE FROM signal_queue
        WHERE expires_at < NOW();

        -- Rate limit kayıtlarını temizle
        DELETE FROM rate_limits
        WHERE expires_at < NOW();

        -- Artık gruba bağlı olmayan üyeleri temizle
        DELETE gm FROM group_members gm
        LEFT  JOIN chat_groups g ON g.group_id = gm.group_id
        WHERE g.group_id IS NULL;
    END$$

DELIMITER ;

SET GLOBAL event_scheduler = ON;


-- ────────────────────────────────────────────────────────────
-- NOTLAR
-- ────────────────────────────────────────────────────────────
-- TABLO YOK: messages       → sadece kullanıcı cihazında (Hive)
-- TABLO YOK: media_files    → P2P direkt transfer
-- TABLO YOK: contacts       → sadece kullanıcı cihazında
-- TABLO YOK: message_pins   → sadece kullanıcı cihazında
-- TABLO YOK: read_receipts  → WebSocket üzerinden direkt
-- TABLO YOK: user_profiles  → username + display_name dışında yok
-- ────────────────────────────────────────────────────────────
