CREATE OR REPLACE PROCEDURE ropidgtfs_hotswap(IN tableName varchar(255))
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	declare
		tableNameActual varchar(255);
		tableNameTmp varchar(255);
		tableNameDrop varchar(255);
	begin
		select tableName || '_actual' into tableNameActual;
		select tableName || '_tmp' into tableNameTmp;
		select tableName || '_old' into tableNameDrop;
	
		EXECUTE format('LOCK %I IN EXCLUSIVE MODE', tableName);
		EXECUTE format('ALTER TABLE %I NO INHERIT %I', tableNameActual, tableName);

        EXECUTE format('ALTER TABLE %I ADD create_batch_id int8 NULL', tableNameTmp);
        EXECUTE format('ALTER TABLE %I ADD COLUMN created_at timestamptz NULL DEFAULT now()', tableNameTmp);
        EXECUTE format('ALTER TABLE %I ADD created_by varchar(150) NULL', tableNameTmp);
        EXECUTE format('ALTER TABLE %I ADD update_batch_id int8 NULL', tableNameTmp);
        EXECUTE format('ALTER TABLE %I ADD COLUMN updated_at timestamptz NULL DEFAULT now()', tableNameTmp);
        EXECUTE format('ALTER TABLE %I ADD updated_by varchar(150) NULL', tableNameTmp);

		EXECUTE format('ALTER TABLE %I RENAME TO %I', tableNameActual, tableNameDrop);
		EXECUTE format('ALTER TABLE %I RENAME TO %I', tableNameTmp, tableNameActual);
		EXECUTE format('ALTER TABLE %I INHERIT %I', tableNameActual, tableName);
		EXECUTE format('DROP TABLE %I', tableNameDrop);
	end;
$procedure$;


CREATE OR REPLACE PROCEDURE ropidgtfs_prepareTmpTable(IN tableName varchar(255))
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	declare
		tableNameActual varchar(255);
		tableNameTmp varchar(255);
		tableNameDrop varchar(255);
	begin
		select tableName || '_tmp' into tableNameTmp;
		
	
		EXECUTE format('create table %I (like %I including all);', tableNameTmp, tableName);
		EXECUTE format('ALTER TABLE %I drop COLUMN create_batch_id', tableNameTmp);
        EXECUTE format('ALTER TABLE %I drop COLUMN created_at', tableNameTmp);
        EXECUTE format('ALTER TABLE %I drop COLUMN created_by', tableNameTmp);
        EXECUTE format('ALTER TABLE %I drop COLUMN update_batch_id', tableNameTmp);
        EXECUTE format('ALTER TABLE %I drop COLUMN updated_at', tableNameTmp);
        EXECUTE format('ALTER TABLE %I drop COLUMN updated_by', tableNameTmp);

	end;
$procedure$;

CREATE OR REPLACE PROCEDURE ropidgtfs_replaceAllSavedTables(in tableNames varchar(255))
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	declare
		currentTable varchar(255);
	begin
		for currentTable in 
			select unnest(string_to_array(tableNames,','))
		loop
			call ropidgtfs_hotswap(currentTable);
	  	end loop;
	end;
$procedure$;

CREATE OR REPLACE PROCEDURE ropidgtfs_prepareTmpTables()
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	begin
		CALL ropidgtfs_cleanTmpTables();
		CALL ropidgtfs_cleanOldTables();
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_agency');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_calendar');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_calendar_dates');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_shapes');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_stop_times');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_stops');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_routes');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_trips');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_cis_stops');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_cis_stop_groups');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_run_numbers');
		CALL ropidgtfs_prepareTmpTable('ropidgtfs_ois');
		alter table ropidgtfs_stop_times_tmp drop computed_dwell_time_seconds;
		alter table ropidgtfs_stop_times_tmp add computed_dwell_time_seconds int2 NOT NULL GENERATED ALWAYS AS (pid.calculate_dwell_time_seconds(arrival_time, departure_time)) stored;
	end
$procedure$;

CREATE OR REPLACE PROCEDURE ropidgtfs_preparePrecomputedTmpTables()
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	begin
		create table "ropidgtfs_precomputed_services_calendar_tmp" (like "ropidgtfs_precomputed_services_calendar" including all);
		create table "ropidgtfs_precomputed_minmax_stop_sequences_tmp" (like "ropidgtfs_precomputed_minmax_stop_sequences" including all);
		create table "ropidgtfs_precomputed_trip_schedule_tmp" (like "ropidgtfs_precomputed_trip_schedule" including all);
	end
$procedure$;

CREATE OR REPLACE PROCEDURE ropidgtfs_cleanTmpTables()
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	begin		
		drop table if exists "ropidgtfs_agency_tmp";
		drop table if exists "ropidgtfs_calendar_tmp";
		drop table if exists "ropidgtfs_calendar_dates_tmp";
		drop table if exists "ropidgtfs_shapes_tmp";
		drop table if exists "ropidgtfs_stop_times_tmp";
		drop table if exists "ropidgtfs_stops_tmp";
		drop table if exists "ropidgtfs_routes_tmp";
		drop table if exists "ropidgtfs_trips_tmp";
		drop table if exists "ropidgtfs_cis_stops_tmp";
		drop table if exists "ropidgtfs_cis_stop_groups_tmp";
		drop table if exists "ropidgtfs_run_numbers_tmp";
		drop table if exists "ropidgtfs_ois_tmp";		
		drop table if exists "ropidgtfs_precomputed_services_calendar_tmp";
		drop table if exists "ropidgtfs_precomputed_minmax_stop_sequences_tmp";
		drop table if exists "ropidgtfs_precomputed_trip_schedule_tmp";
	end
$procedure$;

CREATE OR REPLACE PROCEDURE ropidgtfs_cleanOldTables()
 LANGUAGE plpgsql
 SET search_path FROM CURRENT
AS $procedure$
	begin
		drop table if exists "ropidgtfs_agency_old";
		drop table if exists "ropidgtfs_calendar_old";
		drop table if exists "ropidgtfs_calendar_dates_old";
		drop table if exists "ropidgtfs_shapes_old";
		drop table if exists "ropidgtfs_stop_times_old";
		drop table if exists "ropidgtfs_stops_old";
		drop table if exists "ropidgtfs_routes_old";
		drop table if exists "ropidgtfs_trips_old";
		drop table if exists "ropidgtfs_cis_stops_old";
		drop table if exists "ropidgtfs_cis_stop_groups_old";
		drop table if exists "ropidgtfs_run_numbers_old";
		drop table if exists "ropidgtfs_ois_old";
		drop table if exists "ropidgtfs_precomputed_services_calendar_old";
		drop table if exists "ropidgtfs_precomputed_minmax_stop_sequences_old";
		drop table if exists "ropidgtfs_precomputed_trip_schedule_old";
	end
$procedure$;