#!/usr/bin/perl

use strict;
use warnings;
use File::Basename;
use Test::More;
use lib 't';
use pgsm;

# Get file name and CREATE out file name and dirs WHERE requried
PGSM::setup_files_dir(basename($0));

# CREATE new PostgreSQL node and do initdb
my $node = PGSM->pgsm_init_pg();

$node->append_conf('postgresql.conf',
	"shared_preload_libraries = 'pg_stat_monitor'");

# Dictionary for expected PGSM columns names on different PG server versions
my %pg_versions_pgsm_columns = (
	19 => "application_name,"
	  . "bucket,bucket_done,bucket_start_time,calls,"
	  . "client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time,"
	  . "custom_plan_calls,datname,dbid,elevel,generic_plan_calls,"
	  . "jit_deform_count,jit_deform_time,"
	  . "jit_emission_count,jit_emission_time,jit_functions,jit_generation_time,"
	  . "jit_inlining_count,jit_inlining_time,jit_optimization_count,jit_optimization_time,"
	  . "local_blk_read_time,local_blk_write_time,local_blks_dirtied,local_blks_hit,"
	  . "local_blks_read,local_blks_written,max_exec_time,max_plan_time,mean_exec_time,"
	  . "mean_plan_time,message,min_exec_time,min_plan_time,minmax_stats_since,"
	  . "parallel_workers_launched,parallel_workers_to_launch,"
	  . "pgsm_query_id,planid,plans,query,query_plan,queryid,relations,resp_calls,rows,"
	  . "shared_blk_read_time,shared_blk_write_time,shared_blks_dirtied,"
	  . "shared_blks_hit,shared_blks_read,shared_blks_written,sqlcode,stats_since,"
	  . "stddev_exec_time,stddev_plan_time,temp_blk_read_time,temp_blk_write_time,"
	  . "temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel,"
	  . "total_exec_time,total_plan_time,userid,username,wal_buffers_full,wal_bytes,"
	  . "wal_fpi,wal_records",
	18 => "application_name,"
	  . "bucket,bucket_done,bucket_start_time,calls,"
	  . "client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time,"
	  . "datname,dbid,elevel,jit_deform_count,jit_deform_time,"
	  . "jit_emission_count,jit_emission_time,jit_functions,jit_generation_time,"
	  . "jit_inlining_count,jit_inlining_time,jit_optimization_count,jit_optimization_time,"
	  . "local_blk_read_time,local_blk_write_time,local_blks_dirtied,local_blks_hit,"
	  . "local_blks_read,local_blks_written,max_exec_time,max_plan_time,mean_exec_time,"
	  . "mean_plan_time,message,min_exec_time,min_plan_time,minmax_stats_since,"
	  . "parallel_workers_launched,parallel_workers_to_launch,"
	  . "pgsm_query_id,planid,plans,query,query_plan,queryid,relations,resp_calls,rows,"
	  . "shared_blk_read_time,shared_blk_write_time,shared_blks_dirtied,"
	  . "shared_blks_hit,shared_blks_read,shared_blks_written,sqlcode,stats_since,"
	  . "stddev_exec_time,stddev_plan_time,temp_blk_read_time,temp_blk_write_time,"
	  . "temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel,"
	  . "total_exec_time,total_plan_time,userid,username,wal_buffers_full,wal_bytes,"
	  . "wal_fpi,wal_records",
	17 => "application_name,"
	  . "bucket,bucket_done,bucket_start_time,calls,"
	  . "client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time,"
	  . "datname,dbid,elevel,jit_deform_count,jit_deform_time,"
	  . "jit_emission_count,jit_emission_time,jit_functions,jit_generation_time,"
	  . "jit_inlining_count,jit_inlining_time,jit_optimization_count,jit_optimization_time,"
	  . "local_blk_read_time,local_blk_write_time,local_blks_dirtied,local_blks_hit,"
	  . "local_blks_read,local_blks_written,max_exec_time,max_plan_time,mean_exec_time,"
	  . "mean_plan_time,message,min_exec_time,min_plan_time,minmax_stats_since,"
	  . "pgsm_query_id,planid,plans,query,query_plan,queryid,relations,resp_calls,rows,"
	  . "shared_blk_read_time,shared_blk_write_time,shared_blks_dirtied,"
	  . "shared_blks_hit,shared_blks_read,shared_blks_written,sqlcode,stats_since,"
	  . "stddev_exec_time,stddev_plan_time,temp_blk_read_time,temp_blk_write_time,"
	  . "temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel,"
	  . "total_exec_time,total_plan_time,userid,username,wal_bytes,wal_fpi,wal_records",
	16 => "application_name,blk_read_time,"
	  . "blk_write_time,bucket,bucket_done,bucket_start_time,calls,"
	  . "client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time,"
	  . "datname,dbid,elevel,jit_emission_count,jit_emission_time,jit_functions,"
	  . "jit_generation_time,jit_inlining_count,jit_inlining_time,"
	  . "jit_optimization_count,jit_optimization_time,"
	  . "local_blks_dirtied,local_blks_hit,local_blks_read,"
	  . "local_blks_written,max_exec_time,max_plan_time,mean_exec_time,"
	  . "mean_plan_time,message,min_exec_time,min_plan_time,pgsm_query_id,planid,"
	  . "plans,query,query_plan,queryid,relations,resp_calls,"
	  . "rows,shared_blks_dirtied,shared_blks_hit,shared_blks_read,"
	  . "shared_blks_written,sqlcode,stddev_exec_time,stddev_plan_time,"
	  . "temp_blk_read_time,temp_blk_write_time,temp_blks_read,temp_blks_written,"
	  . "top_query,top_queryid,toplevel,total_exec_time,total_plan_time,"
	  . "userid,username,wal_bytes,wal_fpi,wal_records",
	15 => "application_name,blk_read_time,"
	  . "blk_write_time,bucket,bucket_done,bucket_start_time,calls,"
	  . "client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time,"
	  . "datname,dbid,elevel,jit_emission_count,jit_emission_time,jit_functions,"
	  . "jit_generation_time,jit_inlining_count,jit_inlining_time,"
	  . "jit_optimization_count,jit_optimization_time,"
	  . "local_blks_dirtied,local_blks_hit,local_blks_read,"
	  . "local_blks_written,max_exec_time,max_plan_time,mean_exec_time,"
	  . "mean_plan_time,message,min_exec_time,min_plan_time,pgsm_query_id,planid,"
	  . "plans,query,query_plan,queryid,relations,resp_calls,"
	  . "rows,shared_blks_dirtied,shared_blks_hit,shared_blks_read,"
	  . "shared_blks_written,sqlcode,stddev_exec_time,stddev_plan_time,"
	  . "temp_blk_read_time,temp_blk_write_time,temp_blks_read,temp_blks_written,"
	  . "top_query,top_queryid,toplevel,total_exec_time,total_plan_time,"
	  . "userid,username,wal_bytes,wal_fpi,wal_records",
	14 => "application_name,blk_read_time,"
	  . "blk_write_time,bucket,bucket_done,bucket_start_time,calls,"
	  . "client_ip,cmd_type,cmd_type_text,comments,cpu_sys_time,cpu_user_time,"
	  . "datname,dbid,elevel,local_blks_dirtied,local_blks_hit,local_blks_read,"
	  . "local_blks_written,max_exec_time,max_plan_time,mean_exec_time,"
	  . "mean_plan_time,message,min_exec_time,min_plan_time,pgsm_query_id,planid,"
	  . "plans,query,query_plan,queryid,relations,resp_calls,"
	  . "rows,shared_blks_dirtied,shared_blks_hit,shared_blks_read,"
	  . "shared_blks_written,sqlcode,stddev_exec_time,stddev_plan_time,"
	  . "temp_blks_read,temp_blks_written,top_query,top_queryid,toplevel,"
	  . "total_exec_time,total_plan_time,userid,username,wal_bytes,wal_fpi,wal_records"
);

# Start server
$node->start;

# CREATE EXTENSION and change out file permissions
my ($cmdret, $stdout, $stderr) = $node->psql(
	'postgres',
	'CREATE EXTENSION pg_stat_monitor;',
	extra_params => ['-a']);
is($cmdret, 0, "CREATE PGSM EXTENSION");
PGSM::append_to_file($stdout . "\n");

# Get PGSM columns names FROM PGSM installation in server
($cmdret, $stdout, $stderr) = $node->psql(
	'postgres',
	"SELECT column_name FROM information_schema.columns WHERE table_name = 'pg_stat_monitor' ORDER BY column_name;",
	extra_params => ['-R,']);
is($cmdret, 0,
	"Get columns names in PGSM installation for PG version $PGSM::PG_MAJOR_VERSION"
);
PGSM::append_to_file($stdout . "\n");

# Compare PGSM column names in installation to expected column names
is($stdout, $pg_versions_pgsm_columns{$PGSM::PG_MAJOR_VERSION},
	"Compare supported columns names for PG version $PGSM::PG_MAJOR_VERSION against expected"
);

# Run SELECT statement against expected column names
($cmdret, $stdout, $stderr) = $node->psql(
	'postgres',
	"SELECT $pg_versions_pgsm_columns{$PGSM::PG_MAJOR_VERSION} FROM pg_stat_monitor;",
	extra_params => [ '-a', '-Pformat=aligned', '-Ptuples_only=off' ]);
is($cmdret, 0, "SELECT statement against expected column names");
PGSM::append_to_file($stdout);

# Stop the server
$node->stop;

# Done testing for this testcase file.
done_testing();
