-- Ginxsom Blossom Server Database Schema
-- SQLite database for blob metadata and server configuration

-- Enable foreign key constraints
PRAGMA foreign_keys = ON;

-- Main blobs table for storing blob metadata
CREATE TABLE IF NOT EXISTS blobs (
    sha256 TEXT PRIMARY KEY NOT NULL,           -- SHA-256 hash (64 hex chars)
    size INTEGER NOT NULL,                      -- File size in bytes
    type TEXT NOT NULL,                         -- MIME type
    uploaded_at INTEGER NOT NULL,              -- Unix timestamp
    uploader_pubkey TEXT,                      -- Nostr public key (optional)
    filename TEXT,                             -- Original filename (optional)
    CHECK (length(sha256) = 64),               -- Ensure valid SHA-256 hash length
    CHECK (size >= 0),                         -- Ensure non-negative size
    CHECK (uploaded_at > 0)                    -- Ensure valid timestamp
);

-- Unified configuration table (replaces server_config and auth_config)
CREATE TABLE IF NOT EXISTS config (
    key TEXT PRIMARY KEY NOT NULL,             -- Configuration key
    value TEXT NOT NULL,                       -- Configuration value
    description TEXT,                          -- Human-readable description
    created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),  -- Creation timestamp
    updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))   -- Last update timestamp
);

-- Indexes for performance optimization
CREATE INDEX IF NOT EXISTS idx_blobs_uploaded_at ON blobs(uploaded_at);
CREATE INDEX IF NOT EXISTS idx_blobs_uploader_pubkey ON blobs(uploader_pubkey);
CREATE INDEX IF NOT EXISTS idx_blobs_type ON blobs(type);
CREATE INDEX IF NOT EXISTS idx_config_updated_at ON config(updated_at);

-- Insert default unified configuration
INSERT OR IGNORE INTO config (key, value, description) VALUES
    ('max_file_size', '104857600', 'Maximum file size in bytes (100MB)'),
    ('auth_rules_enabled', 'false', 'Whether authentication rules are enabled for uploads'),
    ('server_name', 'ginxsom', 'Server name for responses'),
    ('admin_pubkey', '', 'Admin public key for API access'),
    ('admin_enabled', 'true', 'Whether admin API is enabled'),
    ('nip42_require_auth', 'false', 'Enable NIP-42 challenge/response authentication'),
    ('nip42_challenge_timeout', '600', 'NIP-42 challenge timeout in seconds'),
    ('nip42_time_tolerance', '300', 'NIP-42 timestamp tolerance in seconds'),
    ('enable_relay_connect', 'true', 'Enable Nostr relay client connections'),
    ('kind_0_content', '{"name":"Ginxsom Blossom Server","about":"A Blossom media server for storing and serving files on Nostr","picture":"","nip05":""}', 'Kind 0 profile metadata content (JSON)'),
    ('kind_10002_tags', '["wss://relay.laantungir.net"]', 'Kind 10002 relay list - JSON array of relay URLs');

-- Authentication rules table for whitelist/blacklist functionality
CREATE TABLE IF NOT EXISTS auth_rules (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    rule_type TEXT NOT NULL,              -- 'pubkey_blacklist', 'pubkey_whitelist',
                                          -- 'hash_blacklist', 'mime_blacklist', 'mime_whitelist'
    rule_target TEXT NOT NULL,            -- The pubkey, hash, or MIME type to match
    operation TEXT NOT NULL DEFAULT '*',  -- 'upload', 'delete', 'list', or '*' for all
    enabled INTEGER NOT NULL DEFAULT 1,   -- 1 = enabled, 0 = disabled
    priority INTEGER NOT NULL DEFAULT 100,-- Lower number = higher priority
    description TEXT,                     -- Human-readable description
    created_by TEXT,                      -- Admin pubkey who created the rule
    created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
    updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),

    -- Constraints
    CHECK (rule_type IN ('pubkey_blacklist', 'pubkey_whitelist',
                         'hash_blacklist', 'mime_blacklist', 'mime_whitelist')),
    CHECK (operation IN ('upload', 'delete', 'list', '*')),
    CHECK (enabled IN (0, 1)),
    CHECK (priority >= 0),

    -- Unique constraint: one rule per type/target/operation combination
    UNIQUE(rule_type, rule_target, operation)
);


-- Indexes for performance optimization
CREATE INDEX IF NOT EXISTS idx_auth_rules_type_target ON auth_rules(rule_type, rule_target);
CREATE INDEX IF NOT EXISTS idx_auth_rules_operation ON auth_rules(operation);
CREATE INDEX IF NOT EXISTS idx_auth_rules_enabled ON auth_rules(enabled);
CREATE INDEX IF NOT EXISTS idx_auth_rules_priority ON auth_rules(priority);
CREATE INDEX IF NOT EXISTS idx_auth_rules_type_operation ON auth_rules(rule_type, operation, enabled);


-- View for storage statistics
CREATE VIEW IF NOT EXISTS storage_stats AS
SELECT
    COUNT(*) as total_blobs,
    SUM(size) as total_bytes,
    AVG(size) as avg_blob_size,
    MIN(uploaded_at) as first_upload,
    MAX(uploaded_at) as last_upload,
    COUNT(DISTINCT uploader_pubkey) as unique_uploaders
FROM blobs;


