CREATE TABLE IF NOT EXISTS groups (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , name TEXT
 , priority INTEGER CHECK(priority IS NOT NULL AND priority > 0)
);

INSERT OR IGNORE INTO groups (id, name, priority) VALUES (0, 'root', 20);
INSERT OR IGNORE INTO groups (id, name, priority) VALUES (1, 'users', 10);
INSERT OR IGNORE INTO groups (id, name, priority) VALUES (2, 'guests', 0);

CREATE TABLE IF NOT EXISTS user_statuses (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , name TEXT
 , UNIQUE(name)
);

INSERT OR IGNORE INTO user_statuses (id, name) VALUES (-1, 'disabled');
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (-2, 'unverified');
INSERT OR IGNORE INTO user_statuses (id, name) VALUES (1, 'enabled');

CREATE TABLE IF NOT EXISTS users (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , group_id INTEGER
 , name TEXT
 , email TEXT
 , hash TEXT
 , status_id INTEGER
 , verification_id INTEGER
 , FOREIGN KEY(group_id) REFERENCES groups(id)
 , FOREIGN KEY(status_id) REFERENCES user_statuses(id)
 , UNIQUE(name)
 , UNIQUE(email)
);

----------------------------------------------------------------------------------------------------
-- Keys represent API keys and auth sessions
CREATE TABLE IF NOT EXISTS user_keys (
   id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(48))))
 , user_id INTEGER
 , name TEXT
 , expiration TEXT
);

----------------------------------------------------------------------------------------------------
-- Printers represent physical devices (really octoprint API targets) that jobs can go to
CREATE TABLE IF NOT EXISTS printer_statuses (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , name TEXT
 , UNIQUE(name)
);

INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (-1, 'error');
INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (0, 'disconnected');
INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (2, 'connecting');
INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (2, 'connected');
INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (3, 'idle');
INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (4, 'running');

CREATE TABLE IF NOT EXISTS printers (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , name TEXT
 , url TEXT
 , api_key TEXT
 , status_id INTEGER
 , last_poll_date TEXT
 , FOREIGN KEY(status_id) REFERENCES printer_statuses(id)
);

----------------------------------------------------------------------------------------------------
-- Files are printables
CREATE TABLE IF NOT EXISTS files (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , user_id INTEGER
 , filename TEXT
 , path TEXT
 , upload_date TEXT
 , FOREIGN KEY(user_id) REFERENCES user(id)
);

----------------------------------------------------------------------------------------------------
-- A job is a request for a copy of a file to be run off
-- For simplicity, jobs also serve as scheduling records
CREATE TABLE IF NOT EXISTS jobs (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , user_id INTEGER NOT NULL
 , file_id INTEGER NOT NULL
 , priority INTEGER CHECK(priority IS NOT NULL AND 0 <= priority)
 , started_at TEXT
 , cancelled_at TEXT
 , finished_at TEXT
 , state TEXT
 , message TEXT
 , printer_id INTEGER
 , FOREIGN KEY(user_id) REFERENCES users(id)
 , FOREIGN KEY(file_id) REFERENCES files(id)
 , FOREIGN KEY(printer_id) REFERENCES printer(id)
);
