
/*
HSS
*/

/*
 KEY VALUE
 */
-- KV
CREATE TABLE KV (
    M TEXT UNIQUE NOT NULL,
    ST TEXT
);
/*
HeartBeat
*/
-- tick clock
CREATE VIEW HB AS SELECT CURRENT_TIMESTAMP AS T;
CREATE TRIGGER TK INSTEAD OF INSERT ON HB 
BEGIN 
    INSERT OR REPLACE INTO KV (M,ST) VALUES ('heartbeat',NEW.T);
END;
INSERT INTO HB VALUES(CURRENT_TIMESTAMP);
/*
 Event Based Input
 */
-- event emit
CREATE TABLE EM (
    ID TEXT NOT NULL,
    MSG TEXT,
    T DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TRIGGER WO BEFORE UPDATE ON EM
BEGIN
    SELECT RAISE (ABORT,'not allowed to update this table');
END;
CREATE TRIGGER HU AFTER INSERT ON EM FOR EACH ROW
BEGIN
    INSERT OR REPLACE INTO KV (M,ST) VALUES (NEW.ID,NEW.MSG);
END;
INSERT INTO EM(ID,MSG) VALUES('HSS','event');

/*
 PREDICATE
 its been a while since this idea flew around your head, predicate engine
 
 name [key to compare] [==,!=,...] [value]
 
 */
CREATE TABLE PRE(
    ID TEXT UNIQUE,
    KEY TEXT,
    OP TEXT,
    VAL TEXT
);
-- operator are supported in this view
-- key vs value
-- TODO key vs key
CREATE VIEW PR0 AS
SELECT PRE.ID AS ID,
       CASE  
            WHEN PRE.OP=='==' THEN (PRE.VAL==KV.ST)
            WHEN PRE.OP=='!=' THEN (PRE.VAL!=KV.ST)
            WHEN PRE.OP=='<' THEN (PRE.VAL>KV.ST)
            WHEN PRE.OP=='>' THEN (PRE.VAL<KV.ST)
            WHEN PRE.OP=='<=' THEN (PRE.VAL>=KV.ST)
            WHEN PRE.OP=='>=' THEN (PRE.VAL<=KV.ST)
            ELSE '(x_X)' 
       END RET,
       INSTR(PRE.ID,'@') AS OFST
FROM PRE INNER JOIN KV ON KV.M == PRE.KEY
UNION SELECT 'true',1,0
UNION SELECT 'false',0,0;
INSERT INTO PRE VALUES('TrueEqTrue','true','==','1');
INSERT INTO PRE VALUES('TrueEqFalse','true','==','0');
INSERT INTO PRE VALUES('FalseEqTrue','false','==','1');
INSERT INTO PRE VALUES('FalseEqFalse','false','==','0');
INSERT INTO PRE VALUES('TrueNEqTrue','true','!=','1');
INSERT INTO PRE VALUES('TrueNEqFalse','true','!=','0');
INSERT INTO PRE VALUES('FalseNEqTrue','false','!=','1');
INSERT INTO PRE VALUES('FalseNEqFalse','false','!=','0');
INSERT INTO KV VALUES('true','1');
INSERT INTO KV VALUES('false','0');

INSERT INTO PRE VALUES('OneBiggerThanTwo','one','>','2');
INSERT INTO PRE VALUES('TwoBiggerThanOne','two','>','1');
INSERT INTO PRE VALUES('OneBiggerThanOne','one','>','1');
INSERT INTO PRE VALUES('TwoBiggerThanTwo','two','>','2');
INSERT INTO PRE VALUES('OneSmallerThanTwo','one','<','2');
INSERT INTO PRE VALUES('TwoSmallerThanOne','two','<','1');
INSERT INTO PRE VALUES('OneSmallerThanOne','one','<','1');
INSERT INTO PRE VALUES('TwoSmallerThanTwo','two','<','2');
INSERT INTO KV VALUES('one','1');
INSERT INTO KV VALUES('two','2');
-- ID WHOM LIKE PRED@GRP
-- will make GRP predicate available
-- all whom share same GRP must must true
CREATE VIEW PR11 AS
SELECT SUBSTR(ID,OFST+1)AS GRP,
       SUBSTR(ID,0,OFST) AS ID,
       RET
FROM PR0
WHERE OFST != 0;
CREATE VIEW PR1 AS
SELECT GRP AS ID, 
       MIN(RET) AS RET,
       INSTR(GRP,'!') AS OFST
FROM PR11
GROUP BY GRP;
INSERT INTO PRE VALUES('twoBig@one','one','<','2');
INSERT INTO PRE VALUES('threeBig@one','one','<','3');
INSERT INTO PRE VALUES('fourBig@one','one','<','4');
INSERT INTO PRE VALUES('fiveBig@one','one','<','5');
INSERT INTO PRE VALUES('twoBig@two','two','<','2');
INSERT INTO PRE VALUES('threeBig@two','two','<','3');
INSERT INTO PRE VALUES('fourBig@two','two','<','4');
INSERT INTO PRE VALUES('fiveBig@two','two','<','5');
-- HAVING GRP LIKE GRP!CHAN
-- WILL GENERATE ANOTHRE PREDICATE
-- WHERE ONLY ONE SHARING THE SAME TAG NEED TO BE TRUE
CREATE VIEW PR22 AS
SELECT SUBSTR(ID,OFST+1) AS CHAN,
       ID,
       RET
FROM PR1
WHERE OFST != 0;
CREATE VIEW PR2 AS
SELECT CHAN AS ID,
       MAX(RET) AS RET 
FROM PR22 
GROUP BY CHAN;
INSERT INTO PRE VALUES('one@two!maybe','one','==','2');
INSERT INTO PRE VALUES('one@one!maybe','one','==','1');

-- ALL VIEW AGGREGATED HERE
CREATE VIEW PRD AS 
SELECT ID,RET FROM PR0
UNION 
SELECT ID,RET FROM PR1
UNION
SELECT ID,RET FROM PR2;
/*
 Finite State Machine
 
 TODO hearthbeat now depend on predicate
 */
-- FSM
CREATE TABLE FSM (
    INI TEXT NOT NULL,
    CLO TEXT NOT NULL,
    TRI TEXT NOT NULL
);
CREATE TRIGGER FSMEM AFTER INSERT ON EM FOR EACH ROW
BEGIN
    INSERT OR REPLACE INTO KV
    SELECT KV.M, FSM.CLO  FROM FSM
    INNER JOIN KV ON KV.ST = TR.INI
    WHERE FSM.TRI='em:' || NEW.ID;
END;
CREATE TRIGGER FSMHB INSTEAD OF INSERT ON HB
BEGIN
    INSERT OR REPLACE INTO KV
    SELECT KV.M, FSM.CLO FROM FSM
    INNER JOIN KV ON KV.ST = FSM.INI
    WHERE FSM.TRI='heartbeat';
END;
INSERT INTO FSM VALUES ('tic','tac','heartbeat');
INSERT INTO FSM VALUES ('tac','tic','heartbeat');
INSERT INTO KV VALUES ('clock','tac');
INSERT INTO FSM VALUES ('wait','pong','em:ping');
INSERT INTO FSM VALUES ('pong','wait','heartbeat');
INSERT INTO KV VALUES ('poke','wait');
/*
 RENDERING
 *//*
CREATE TABLE GRID (
    CO INTEGER UNIQUE,
    RO INTEGER UNIQUE,
    CL TEXT
);

-- view that argregate this into a matrix
CREATE VIEW RNG10 AS 
          SELECT 0 AS I
UNION ALL SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9;
CREATE VIEW RNG100 AS
SELECT U.I*D.I AS I
FROM RNG10 AS U
JOIN RNG10 AS D
ORDER BY I ASC;



CREaTE VIEW SCR AS
SELECT GROUP_CONCAT(CL) FROM (
    SELECT COALESCE(GRID.CL,' ') AS CL
    FROM RNG10 AS CO 
    JOIN RNG10 AS RO
    LEFT JOIN GRID 
    ON GRID.CO = CO.I 
    AND GRID.RO = RO.I
);
/**/
INSERT INTO HB VALUES(0);
