CREATE TABLE func_merge_changes(
    merge INTEGER NOT NULL
);

CREATE TRIGGER
    func_merge_changes_bi_1
BEFORE INSERT ON
    func_merge_changes
FOR EACH ROW WHEN
    NEW.merge = 1
BEGIN

    UPDATE nodes_tomerge                 SET resolve = 1;
    UPDATE entities_tomerge               SET resolve = 1;
    UPDATE entity_contact_methods_tomerge SET resolve = 1;
    UPDATE identities_tomerge             SET resolve = 1;
    UPDATE hubs_tomerge                   SET resolve = 1;
    UPDATE projects_tomerge               SET resolve = 1;
    UPDATE project_status_tomerge         SET resolve = 1;
    UPDATE task_status_tomerge            SET resolve = 1;
    UPDATE issue_status_tomerge           SET resolve = 1;
    UPDATE tasks_tomerge                  SET resolve = 1;
    UPDATE issues_tomerge                 SET resolve = 1;

    -- First of all the identities
    INSERT INTO
        hub_entities(
            hub_id,
            entity_id
        )
    SELECT DISTINCT
        ph.hub_id,
        c.identity_id
    -- Find related hubs of change_nodes.node_id
    FROM
        change_nodes cn
    INNER JOIN
        nodes_tree nt
    ON
        nt.child = cn.node_id
    INNER JOIN
        project_hubs ph
    ON
        ph.project_id = nt.parent
    -- Match with identity of the change
    INNER JOIN
        changes c
    ON
        c.id = cn.change_id
    WHERE
        cn.hub_change > 0
    ;


    -- TODO exclude for associated existing rows in hub_entities
    INSERT INTO
        project_entities(
            project_id,
            entity_id
        )
    SELECT DISTINCT
        n.project_id,
        c.identity_id
    FROM
        change_nodes cn
    INNER JOIN
        nodes n
    ON
        n.id = cn.node_id AND n.project_id IS NOT NULL
    INNER JOIN
        changes c
    ON
        c.id = cn.change_id
    WHERE
        cn.project_change > 0
    ;


    -- TODO split this union up so we can check for duplicates? (no IGNORE)
    INSERT OR IGNORE INTO
        hub_related_changes(
            hub_id,
            prefix,
            change_id,
            sha1
        )
    -- Changes to hub/project/status nodes, mapped to a hub
    SELECT DISTINCT
        ph.hub_id,
        SUBSTR(c.uuid, 1, 1),
        cn.change_id,
        c.uuid
    FROM
        change_nodes cn
    INNER JOIN
        nodes_tree nt
    ON
        nt.child = cn.node_id
    INNER JOIN
        project_hubs ph
    ON
        ph.project_id = nt.parent
    INNER JOIN
        changes c
    ON
        c.id = cn.change_id
    WHERE
        cn.hub_change > 0
    -- And also changes to identities involved with hubs/projects
    UNION SELECT DISTINCT
        he.hub_id,
        SUBSTR(c.uuid, 1, 1),
        cn.change_id,
        c.uuid
    FROM
        change_nodes cn
    INNER JOIN
        hub_entities he
    ON
        he.entity_id = cn.node_id
    INNER JOIN
        changes c
    ON
        c.id = cn.change_id
    WHERE
        cn.hub_change > 0
    ;


    INSERT OR IGNORE INTO
        project_related_changes(
            project_id,
            prefix,
            change_id,
            sha1
        )
    -- Changes to task/issue nodes, mapped to a project
    SELECT
        n.project_id,
        SUBSTR(c.uuid, 1, 1),
        c.id,
        c.uuid
    FROM
        change_nodes cn
    INNER JOIN
        nodes n
    ON
        n.id = cn.node_id AND n.project_id IS NOT NULL
    INNER JOIN
        changes c
    ON
        c.id = cn.change_id
    WHERE
        cn.project_change > 0
    -- And also changes to identities involved with projects/projects
    -- TODO excluding associated identities in hub_entities
    UNION SELECT
        pe.project_id,
        SUBSTR(c.uuid, 1, 1),
        c.id,
        c.uuid
    FROM
        change_nodes cn
    INNER JOIN
        project_entities pe
    ON
        pe.entity_id = cn.node_id
    INNER JOIN
        changes c
    ON
        c.id = cn.change_id
    WHERE
        cn.project_change > 0 -- AND cn.hub_change < 1 ?
    ;

    -- TODO Keep this around, and use it for when projects pushed to a hub?
--    DELETE FROM change_nodes;

    SELECT RAISE(IGNORE);

END;
