DELETE FROM ft_attr WHERE key='is_virtual' AND value IS NULL;

UPDATE cond_rd_seq SET seq_num = seq_num + 1112 WHERE seq_num != 1111;
UPDATE cond_rd_seq SET seq_num = CASE WHEN seq_num = 1111 THEN 0 ELSE seq_num - 1111 END;
SET enable_mergejoin='on'; /* workaround for MDB where merge-joins are disabled by default
                              but it is crucial for performance in this particular case */
/*convert obsolete stop types to bus-stop*/
UPDATE ft SET ft_type_id = 671 /*transport-bus-stop*/
WHERE ft_type_id IN
(
    686, /*transport-taxi-stop*/
    681, /*transport-bus-terminal*/
    662  /*transport-tram-stop*/
);

/**********************************************************************
*                         COLLECTING                                  *
**********************************************************************/

/*collect operating transport systems*/
CREATE TEMPORARY TABLE operating_system AS
SELECT ft_id FROM ft
WHERE ft_type_id = 631 /*transport-system*/
EXCEPT
SELECT ft_id FROM ft_attr WHERE key='not_operating';

/*collect operating transport routes*/
CREATE TEMPORARY TABLE operating_route AS
SELECT ft.ft_id FROM ft
JOIN operating_system ON (p_ft_id = operating_system.ft_id)
WHERE ft_type_id IN
(
    2201, /*transport-bus-route*/
    2202, /*transport-trolleybus-route*/
    2203, /*transport-tram-route*/
    2204, /*transport-minibus-route*/
    625, /*transport-metro-light-line*/
    626, /*transport-metro-tram-line*/
    627, /*transport-metro-monorail-line*/
    628, /*transport-metro-bus-line*/
    629, /*transport-metro-cable-line*/
    630, /*transport-metro-funicular-line*/
    632, /*transport-metro-line*/
    2208 /*transport-waterway-route*/
)
EXCEPT
SELECT ft_id FROM ft_attr WHERE key = 'not_operating';

/*collect operating transport route aliases*/
CREATE TEMPORARY TABLE operating_alias AS
SELECT ft.ft_id FROM ft
JOIN operating_route ON (p_ft_id = operating_route.ft_id)
WHERE ft_type_id = 2211; /*transport_route_alias*/

/*collect operating transport threads*/
CREATE TEMPORARY TABLE operating_thread AS
SELECT ft.ft_id FROM ft
JOIN operating_route ON (p_ft_id = operating_route.ft_id)
WHERE ft_type_id IN
(
    2205, /*transport-bus-thread*/
    2212, /*transport-tram-thread*/
    2213, /*transport-waterway-thread*/
    2214 /*transport-metro-thread*/
)
EXCEPT
SELECT ft_id FROM ft_attr WHERE key = 'not_operating';

/*collect operating transport thread connectors.
  thread connector is considered operating, if both connecting threads are operating*/
CREATE TEMPORARY TABLE operating_thread_connector AS
SELECT ft.ft_id FROM ft
JOIN ft_ft ft_ft_src ON (ft.ft_id = ft_ft_src.master_ft_id)
JOIN ft_ft ft_ft_dst ON (ft.ft_id = ft_ft_dst.master_ft_id)
JOIN operating_thread op_thread_src ON (ft_ft_src.slave_ft_id = op_thread_src.ft_id)
JOIN operating_thread op_thread_dst ON (ft_ft_dst.slave_ft_id = op_thread_dst.ft_id)
WHERE ft_type_id IN
(
    2217, /*transport-bus-thread-connector*/
    2218, /*transport-tram-thread-connector*/
    2219, /*transport-waterway-thread-connector*/
    2220 /*transport-metro-thread-connector*/
)
AND ft_ft_src.role = 'src_thread'
AND ft_ft_dst.role = 'dst_thread';

/*union operating transport threads and transport thread connectors*/
CREATE TEMPORARY TABLE operating_thread_and_connector AS
SELECT ft_id FROM operating_thread
UNION
SELECT ft_id FROM operating_thread_connector;

/*collect operating transport thread_stops*/
CREATE TEMPORARY TABLE operating_thread_stop AS
SELECT ft.ft_id FROM ft
JOIN operating_thread_and_connector ON (p_ft_id = operating_thread_and_connector.ft_id)
WHERE ft_type_id = 2206; /*transport-thread-stop*/

/*collect operating stops*/
CREATE TEMPORARY TABLE stops_with_thread AS
SELECT ft.ft_id FROM ft
JOIN ft_ft ON (master_ft_id = ft.ft_id AND role = 'assigned_thread_stop')
JOIN operating_thread_stop ON (slave_ft_id = operating_thread_stop.ft_id)
WHERE ft_type_id IN
(
    633, /*transport-metro-station*/
    671, /*transport-bus-stop*/
    602, /*transport-waterway-wharf*/
    603, /*transport-waterway-seaport*/
    604  /*transport-waterway-riverport*/
);
CREATE TEMPORARY TABLE operating_stop AS
SELECT DISTINCT ft.ft_id FROM ft
JOIN ft_ft ON ft_ft.slave_ft_id = ft.ft_id AND role='assigned'
JOIN operating_route ON ft_ft.master_ft_id = operating_route.ft_id;
/*mark stops without threads as waypoints*/
INSERT INTO ft_attr (ft_id, key, value)
SELECT ft_id, 'waypoint', '1' FROM operating_stop os
WHERE NOT EXISTS (SELECT FROM stops_with_thread st WHERE os.ft_id = st.ft_id)
ON CONFLICT DO NOTHING;

/*collect operating exits*/
CREATE TEMPORARY TABLE operating_exit AS
SELECT DISTINCT ft.ft_id, ft.p_ft_id FROM ft
JOIN operating_stop ON (p_ft_id = operating_stop.ft_id)
WHERE ft_type_id = 634; /*transport-metro-exit*/
/*mark exits with waypoints stops waypoints as well*/
INSERT INTO ft_attr (ft_id, key, value)
SELECT oe.ft_id, 'waypoint', '1' FROM operating_exit oe
WHERE NOT EXISTS (SELECT FROM stops_with_thread st WHERE oe.p_ft_id = st.ft_id);

/*collect operating passageways*/
CREATE TEMPORARY TABLE operating_passageway AS
SELECT ft.ft_id FROM ft
JOIN ft_ft AS exit ON (exit.master_ft_id = ft.ft_id AND exit.role = 'exit')
JOIN operating_exit ON (exit.slave_ft_id = operating_exit.ft_id)
JOIN ft_ft station ON (station.master_ft_id = ft.ft_id AND station.role = 'station')
JOIN operating_stop ON (station.slave_ft_id = operating_stop.ft_id)
WHERE ft_type_id = 2210 /*transport-metro-passageway*/
EXCEPT
SELECT ft_id FROM ft_attr WHERE key = 'not_operating';

/*collect operating transitions*/
CREATE TEMPORARY TABLE operating_transition AS
SELECT ft.ft_id FROM ft
JOIN ft_ft AS a ON (a.master_ft_id = ft.ft_id AND a.role = 'station_a')
JOIN operating_stop AS operating_stop_a
    ON (a.slave_ft_id = operating_stop_a.ft_id)
JOIN ft_ft AS b ON (b.master_ft_id = ft.ft_id AND b.role = 'station_b')
JOIN operating_stop AS operating_stop_b
    ON (b.slave_ft_id = operating_stop_b.ft_id)
WHERE ft_type_id = 2209 /*transport-metro-transition*/
EXCEPT
SELECT ft_id FROM ft_attr WHERE key = 'not_operating';

/*collect operating transport_passageway_boarding*/
CREATE TEMPORARY TABLE operating_transport_passageway_boarding AS
SELECT ft.ft_id FROM ft
JOIN ft_ft AS prev_station ON (prev_station.master_ft_id = ft.ft_id AND prev_station.role='station_previous')
JOIN operating_stop ON (prev_station.slave_ft_id = operating_stop.ft_id)
JOIN operating_passageway ON (ft.p_ft_id = operating_passageway.ft_id)
WHERE ft.ft_type_id = 2215;

/*collect operating transport_transition_boarding*/
CREATE TEMPORARY TABLE operating_transport_transition_boarding AS
SELECT ft.ft_id FROM ft
JOIN ft_ft AS prev_station ON (prev_station.master_ft_id = ft.ft_id AND prev_station.role='station_previous')
JOIN operating_stop ON (prev_station.slave_ft_id = operating_stop.ft_id)
JOIN operating_transition ON (ft.p_ft_id = operating_transition.ft_id)
WHERE ft.ft_type_id = 2216 AND
    (
        NOT EXISTS
        (SELECT slave_ft_id FROM ft_ft ft_next WHERE ft_next.master_ft_id=ft.ft_id AND ft_next.role='station_next')
        OR EXISTS
        (SELECT slave_ft_id FROM ft_ft ft_next JOIN operating_stop os ON (ft_next.slave_ft_id=os.ft_id) WHERE ft_next.master_ft_id=ft.ft_id AND ft_next.role='station_next')
    );

/*collect operating freq_dt*/
CREATE TEMPORARY TABLE operating_calendar AS
SELECT ft.ft_id FROM ft
LEFT JOIN operating_system ON (p_ft_id = operating_system.ft_id)
LEFT JOIN operating_thread ON (p_ft_id = operating_thread.ft_id)
WHERE ft_type_id = 2207 /*transport-freq-dt*/
AND
(
    operating_system.ft_id IS NOT NULL
    OR operating_thread.ft_id IS NOT NULL
);

/*collect not-operating transport objects to delete*/
CREATE TEMPORARY TABLE deleted_ft AS
SELECT ft_id FROM ft
WHERE ft_type_id IN
(
    631,  /*transport-system*/

    2201, /*transport-bus-route*/
    2202, /*transport-trolleybus-route*/
    2203, /*transport-tram-route*/
    2204, /*transport-minibus-route*/
    625,  /*transport-metro-light-line*/
    626,  /*transport-metro-tram-line*/
    627,  /*transport-metro-monorail-line*/
    628,  /*transport-metro-bus-line*/
    629,  /*transport-metro-cable-line*/
    630,  /*transport-metro-funicular-line*/
    632,  /*transport-metro-line*/
    2208, /*transport-waterway-route*/

    2211, /*transport_route_alias*/

    2205, /*transport-bus-thread*/
    2212, /*transport-tram-thread*/
    2213, /*transport-waterway-thread*/
    2214, /*transport-metro-thread*/

    2217, /*transport-bus-thread-connector*/
    2218, /*transport-tram-thread-connector*/
    2219, /*transport-waterway-thread-connector*/
    2220, /*transport-metro-thread-connector*/

    2206, /*transport-thread-stop*/

    633,  /*transport-metro-station*/
    671,  /*transport-bus-stop*/
    602,  /*transport-waterway-wharf*/
    603,  /*transport-waterway-seaport*/
    604,  /*transport-waterway-riverport*/

    634,  /*transport-metro-exit*/

    2210, /*transport-metro-passageway*/
    2209, /*transport-metro-transition*/

    2207 /*transport-freq-dt*/,

    2215 /*transport_passageway_boarding*/,
    2216 /*transport_transition_boarding*/
)
EXCEPT
SELECT ft_id FROM operating_system
EXCEPT
SELECT ft_id FROM operating_route
EXCEPT
SELECT ft_id FROM operating_alias
EXCEPT
SELECT ft_id FROM operating_thread_and_connector
EXCEPT
SELECT ft_id FROM operating_thread_stop
EXCEPT
SELECT ft_id FROM operating_stop
EXCEPT
SELECT ft_id FROM operating_exit
EXCEPT
SELECT ft_id FROM operating_passageway
EXCEPT
SELECT ft_id FROM operating_transition
EXCEPT
SELECT ft_id FROM operating_calendar
EXCEPT
SELECT ft_id FROM operating_transport_passageway_boarding
EXCEPT
SELECT ft_id FROM operating_transport_transition_boarding;

/**********************************************************************
*                           DELETING                                  *
**********************************************************************/
CREATE INDEX ON operating_thread_and_connector (ft_id);
CREATE INDEX ON deleted_ft (ft_id);

/**** Delete all unused roads ****/

/*Delete not-operating threads from ft_rd_el*/
DELETE FROM ft_rd_el
USING ft_rd_el thread_rd_el
LEFT JOIN operating_thread_and_connector ON (thread_rd_el.ft_id = operating_thread_and_connector.ft_id)
WHERE ft_rd_el.ft_id = thread_rd_el.ft_id
AND operating_thread_and_connector.ft_id IS NULL;

/*Delete all rd_jc-s and rd_el-s not used in transport_threads*/
DELETE FROM rd_el
WHERE rd_el_id IN
(
    SELECT rd_el_id FROM rd_el
    EXCEPT
    SELECT rd_el_id FROM ft_rd_el
);

DELETE FROM rd_jc
WHERE rd_jc_id IN
(
    SELECT rd_jc_id FROM rd_jc
    EXCEPT
    SELECT f_rd_jc_id FROM rd_el
    EXCEPT
    SELECT t_rd_jc_id FROM rd_el
);

/*Delete all conditions on deleted rd_el-s*/
DELETE FROM cond_rd_seq
WHERE cond_seq_id IN
(
    SELECT DISTINCT cond_seq_id FROM cond
    WHERE cond_id IN
    (
        SELECT cond_id FROM cond
        WHERE cond_seq_id IN
        (
            SELECT cond_seq_id FROM cond_rd_seq
            WHERE rd_el_id IN
            (
                SELECT rd_el_id FROM cond_rd_seq
                EXCEPT
                SELECT rd_el_id FROM rd_el
            )
        )
    )
);

 DELETE FROM cond
 WHERE cond_seq_id IN
(
    SELECT cond_seq_id FROM cond
    EXCEPT
    SELECT cond_seq_id FROM cond_rd_seq
);

 DELETE FROM cond_dt
 WHERE cond_id IN
(
    SELECT cond_id FROM cond_dt
    EXCEPT
    SELECT cond_id FROM cond
);

/**** Cascade delete all not-operating ft ****/
DELETE FROM ft_isocode
USING deleted_ft
WHERE ft_isocode.ft_id = deleted_ft.ft_id;

DELETE FROM ft_nm
USING deleted_ft
WHERE ft_nm.ft_id = deleted_ft.ft_id;

DELETE FROM ft_source
USING deleted_ft
WHERE ft_source.ft_id = deleted_ft.ft_id;

DELETE FROM ft_attr
USING deleted_ft
WHERE ft_attr.ft_id = deleted_ft.ft_id;

DELETE FROM ft_ft
USING deleted_ft
WHERE ft_ft.master_ft_id = deleted_ft.ft_id
OR ft_ft.slave_ft_id = deleted_ft.ft_id;

DELETE FROM ft_rd_el
USING deleted_ft
WHERE ft_rd_el.ft_id = deleted_ft.ft_id;

DELETE FROM node_isocode
USING deleted_ft, ft_center
WHERE ft_center.ft_id = deleted_ft.ft_id
AND ft_center.node_id = node_isocode.node_id;

DELETE FROM node
USING deleted_ft, ft_center
WHERE ft_center.ft_id = deleted_ft.ft_id
AND ft_center.node_id = node.node_id;

DELETE FROM ft_center
USING deleted_ft
WHERE ft_center.ft_id = deleted_ft.ft_id;

DELETE FROM ft_edge
USING deleted_ft
WHERE ft_edge.ft_id = deleted_ft.ft_id;

DELETE FROM face_edge
USING deleted_ft, ft_face
WHERE ft_face.ft_id = deleted_ft.ft_id
AND ft_face.face_id = face_edge.face_id;

DELETE FROM face_isocode
USING deleted_ft, ft_face
WHERE ft_face.ft_id = deleted_ft.ft_id
AND ft_face.face_id = face_isocode.face_id;

DELETE FROM face
USING deleted_ft, ft_face
WHERE ft_face.ft_id = deleted_ft.ft_id
AND ft_face.face_id = face.face_id;

DELETE FROM ft_face
USING deleted_ft
WHERE ft_face.ft_id = deleted_ft.ft_id;

DELETE FROM ft
USING deleted_ft
WHERE ft.ft_id = deleted_ft.ft_id;

/* delete mtr id for exits sharing value with stop (parent) */
DELETE FROM ONLY ft_source a
USING ft, ft_source b
WHERE b.source_type_id = 3 AND
    a.source_type_id = 3 AND
    a.source_id = b.source_id AND
    ft.ft_type_id = 634 AND
    ft.p_ft_id = b.ft_id AND
    a.ft_id=ft.ft_id;
