-- name: migration-0000-create-printers#
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
 , stream_url TEXT
 , api_key TEXT
 , status_id INTEGER
 , last_poll_date TEXT
 , FOREIGN KEY(status_id) REFERENCES printer_statuses(id)
);

-- name: migration-0001-create-printer-occupied-state#
-- Create a state representing that the printer needs to be unloaded after a print
INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (5, 'occupied');

-- name: migration-0002-create-printer-chassis#
CREATE TABLE IF NOT EXISTS printer_chassis (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , name TEXT
 , limit_x INTEGER
 , limit_y INTEGER
 , limit_z INTEGER
 , limit_bed INTEGER
 , limit_hotend INTEGER
 , limit_tools INTEGER
 , UNIQUE(name)
);

INSERT INTO printer_chassis (name, limit_x, limit_y, limit_z, limit_bed, limit_hotend, limit_tools) VALUES (
   'Creality CR-10v3', 310, 310, 400, 100, 260, 1
);

INSERT INTO printer_chassis (name, limit_x, limit_y, limit_z, limit_bed, limit_hotend, limit_tools) VALUES (
   'Prusa Mini', 180, 180, 180, 100, 280, 1
);

INSERT INTO printer_chassis (name, limit_x, limit_y, limit_z, limit_bed, limit_hotend, limit_tools) VALUES (
   'Prusa i3', 250, 210, 210, 120, 300, 1
);

INSERT INTO printer_chassis (name, limit_x, limit_y, limit_z, limit_bed, limit_hotend, limit_tools) VALUES (
   'Prusa XL', 360, 360, 360, 120, 300, 5
);

ALTER TABLE printers ADD chassis_id INTEGER REFERENCES printer_chassis(id) DEFAULT 1;

-- name: migration-0003-create-printer-filament#
CREATE TABLE IF NOT EXISTS filament (
   id INTEGER PRIMARY KEY AUTOINCREMENT
 , name TEXT
 , UNIQUE(name)
);

INSERT OR IGNORE INTO filament (name) VALUES ('PLA');
INSERT OR IGNORE INTO filament (name) VALUES ('ABS');
INSERT OR IGNORE INTO filament (name) VALUES ('PETG');

ALTER TABLE printers ADD filament_id INTEGER REFERENCES filament(id) DEFAULT 1;


-- name: migration-0004-create-printer-enabled#
ALTER TABLE printers ADD enabled BOOLEAN DEFAULT TRUE;

-- name: migration-0005-create-printer-nozzle#
ALTER TABLE printers ADD nozzle_diameter FLOAT DEFAULT 0.4;

-- name: try-create-printer^
INSERT INTO printers (
   name
 , url
 , api_key
 , status_id
)
VALUES (:name, :url, :api_key, :sid)
RETURNING
   id
;

-- name: fetch-printer^
SELECT
   p.id
 , p.name
 , p.url
 , p.stream_url
 , p.api_key
 , p.last_poll_date
 , p.filament_id
 , p.chassis_id
 , p.enabled
 , s.name as status
 , p.nozzle_diameter
FROM printers p
INNER JOIN printer_statuses s ON p.status_id = s.id
WHERE p.id = :pid
;

-- name: list-printers
SELECT
   p.id
 , p.name
 , p.url
 , p.stream_url
 , p.api_key
 , p.last_poll_date
 , s.name as status
 , p.enabled
 , f.name as filament_name
 , c.name as machine_name
 , c.limit_x
 , c.limit_y
 , c.limit_z
 , c.limit_bed
 , c.limit_hotend
 , p.nozzle_diameter
FROM printers p
INNER JOIN printer_statuses s ON p.status_id = s.id
INNER JOIN filament f on p.filament_id = f.id
INNER JOIN printer_chassis c on p.chassis_id = c.id
;

-- name: list-idle-printers
SELECT
   p.id as id
 , c.limit_x
 , c.limit_y
 , c.limit_z
 , c.limit_bed
 , c.limit_hotend
 , p.nozzle_diameter
 , p.filament_id
FROM printers p
LEFT JOIN (SELECT id, printer_id FROM jobs WHERE finished_at IS NULL) j
   ON p.id = j.printer_id
INNER JOIN printer_statuses s
   ON p.status_id = s.id
INNER JOIN printer_chassis c
   ON p.chassis_id = c.id
INNER JOIN filament f
   ON p.filament_id = f.id
WHERE
   j.id IS NULL
   AND s.name = 'idle'
   AND p.enabled = TRUE
;

-- name: update-printer-status!
UPDATE printers
SET
   status_id = (SELECT id FROM printer_statuses WHERE name = :status or id = :status)
 , last_poll_date = datetime('now')
WHERE
   id = :pid
;

-- name: edit-printer!
UPDATE printers
SET
   name = :name
 , url = :url
 , stream_url = :stream_url
 , api_key = :api_key
 , filament_id = :filament_id
 , chassis_id = :chassis_id
 , enabled = :enabled
 , nozzle_diameter = :nozzle_diameter
WHERE
   id = :id
;

-- name: list-chassis
SELECT
   id
 , name
FROM printer_chassis
;

-- name: list-filament
SELECT
   id
 , name
 FROM filament
 ;

-- name: create-filament^
INSERT OR IGNORE INTO filament (
   name
)
VALUES (
   :name
)
RETURNING
   id
;

-- name: fetch-filament^
SELECT *
FROM filament
WHERE name = :name
;
