CREATE TABLE func_end_change(
    id INTEGER NOT NULL,
    action_format VARCHAR NOT NULL,
    action_topic_id_1 INTEGER,
    action_topic_id_2 INTEGER,
    identity_id INTEGER NOT NULL,
    message VARCHAR NOT NULL,
    uuid VARCHAR(40)
);


CREATE TRIGGER
    func_end_change_bi_1
BEFORE INSERT ON
    func_end_change
FOR EACH ROW
BEGIN

    SELECT debug(
        NEW.id,
        NEW.action_format,
        NEW.action_topic_id_1,
        NEW.action_topic_id_2,
        NEW.identity_id,
        NEW.message,
        NEW.uuid
    );

    UPDATE
        changes
    SET
        action_format     = NEW.action_format,
        action_topic_id_1 = NEW.action_topic_id_1,
        action_topic_id_2 = NEW.action_topic_id_2,
        identity_id       = NEW.identity_id,
        message           = NEW.message,
        action = (
            SELECT
                printf(NEW.action_format, t1.id, t2.id)
            FROM
                (SELECT 1)
            LEFT JOIN
                topics t1
            ON
                t1.id = NEW.action_topic_id_1
            LEFT JOIN
                topics t2
            ON
                t2.id = NEW.action_topic_id_2
        ),
        yaml = yaml || (
            SELECT
                '-' || x'0A'
                || CASE WHEN
                    instr(NEW.action_format, ' ')
                THEN
                    '  action_format: ''' || NEW.action_format || '''' || x'0A'
                ELSE
                    '  action_format: ' 
                    || COALESCE(NEW.action_format,'~') || x'0A'
                END
                || '  action_topic_uuid_1: '
                || COALESCE(t1.uuid, '~') || x'0A'
                || '  action_topic_uuid_2: '
                || COALESCE(t2.uuid, '~') || x'0A'
                || '  identity_uuid: ' || COALESCE(i.uuid,'~') || x'0A'
                ||
                    CASE WHEN
                        NEW.message IS NULL
                    THEN
                        '  message: ~' || x'0A'
                    WHEN
                        NEW.message = '-'
                    THEN
                        '  message: ''-''' || x'0A'
                    WHEN
                        instr(NEW.message, x'0A') OR
                        instr(NEW.message, '\\') OR
                        instr(NEW.message, '"')
                    THEN
                        '  message: "' 
                        || REPLACE(
                              REPLACE(
                                REPLACE(NEW.message, '\\', '\\\\'),
                                x'0A', '\n'), '"', '\"')
                        || '"' || x'0A'
                    WHEN
                        instr(NEW.message, ' ') OR
                        NEW.message = '' -- not at all sufficient
                    THEN
                        '  message: ''' || NEW.message || '''' || x'0A'
                    ELSE
                        '  message: ' || NEW.message || x'0A'
                    END
            FROM
                (SELECT 1)
            LEFT JOIN
                topics t1
            ON
                t1.id = NEW.action_topic_id_1
            LEFT JOIN
                topics t2
            ON
                t2.id = NEW.action_topic_id_2
            LEFT JOIN
                topics i
            ON
                i.id = NEW.identity_id
        )
    WHERE
        id = NEW.id
    ;


    /*
        For a locally created change changes.uuid is always the SHA1
        hash of the changes.yaml column, and the changes.invalid column
        is 0.
        
        For an imported change the changes.uuid is always set to the
        received uuid, and the changes.invalid is based on whether the
        local and remote uuids match.
    */

    UPDATE
        changes
    SET
        uuid =
            CASE WHEN
                NEW.uuid IS NULL
            THEN
                sha1_hex(yaml)
            ELSE
                NEW.uuid
            END,
        valid =
            CASE WHEN
                NEW.uuid IS NULL OR NEW.uuid = sha1_hex(yaml)
            THEN
                1
            ELSE
                0
            END
    WHERE
        id = NEW.id
    ;


/*
        CASE WHEN
            c.uuid != NEW.uuid
        THEN
            RAISE(ABORT, 'Bif::Err::UUIDMismatch')
        ELSE
            RAISE(IGNORE)
        END
    FROM
        changes c
    WHERE
        c.id = NEW.id
    ;
*/

    /*
        Now that identity_id has been set we can do some cleanup of the
        project/entities relationship
    */
    UPDATE
        project_changes
    SET
        map_entities = 1
    WHERE
        change_id = NEW.id AND map_entities = 0
    ;

    SELECT RAISE(IGNORE);
END;
