# Copyright (c) 2024-2025, PostgreSQL Global Development Group

use strict;
use warnings FATAL => 'all';
use File::Path qw(mkpath);
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;

my $node = PostgreSQL::Test::Cluster->new('node');

$node->init;

# Create temporary directories for the extension control files
my $ext_dir = PostgreSQL::Test::Utils::tempdir();
mkpath("$ext_dir/extension");
my $ext_dir2 = PostgreSQL::Test::Utils::tempdir();
mkpath("$ext_dir2/extension");

my $ext_name = "test_custom_ext_paths";
create_extension($ext_name, $ext_dir);
create_extension($ext_name, $ext_dir2);

my $ext_name2 = "test_custom_ext_paths_using_directory";
mkpath("$ext_dir/$ext_name2");
create_extension($ext_name2, $ext_dir, $ext_name2);

# Use the correct separator and escape \ when running on Windows.
my $sep = $windows_os ? ";" : ":";
$node->append_conf(
	'postgresql.conf', qq{
extension_control_path = '\$system$sep@{[ $windows_os ? ($ext_dir =~ s/\\/\\\\/gr) : $ext_dir ]}$sep@{[ $windows_os ? ($ext_dir2 =~ s/\\/\\\\/gr) : $ext_dir2 ]}'
});

# Start node
$node->start;

my $ecp = $node->safe_psql('postgres', 'show extension_control_path;');

is($ecp, "\$system$sep$ext_dir$sep$ext_dir2",
	"custom extension control directory path configured");

$node->safe_psql('postgres', "CREATE EXTENSION $ext_name");
$node->safe_psql('postgres', "CREATE EXTENSION $ext_name2");

my $ret = $node->safe_psql('postgres',
	"select * from pg_available_extensions where name = '$ext_name'");
is( $ret,
	"test_custom_ext_paths|1.0|1.0|Test extension_control_path",
	"extension is installed correctly on pg_available_extensions");

$ret = $node->safe_psql('postgres',
	"select * from pg_available_extension_versions where name = '$ext_name'");
is( $ret,
	"test_custom_ext_paths|1.0|t|t|f|t|||Test extension_control_path",
	"extension is installed correctly on pg_available_extension_versions");

$ret = $node->safe_psql('postgres',
	"select * from pg_available_extensions where name = '$ext_name2'");
is( $ret,
	"test_custom_ext_paths_using_directory|1.0|1.0|Test extension_control_path",
	"extension is installed correctly on pg_available_extensions");

$ret = $node->safe_psql('postgres',
	"select * from pg_available_extension_versions where name = '$ext_name2'"
);
is( $ret,
	"test_custom_ext_paths_using_directory|1.0|t|t|f|t|||Test extension_control_path",
	"extension is installed correctly on pg_available_extension_versions");

# Ensure that extensions installed on $system is still visible when using with
# custom extension control path.
$ret = $node->safe_psql('postgres',
	"select count(*) > 0 as ok from pg_available_extensions where name = 'plpgsql'"
);
is($ret, "t",
	"\$system extension is installed correctly on pg_available_extensions");


$ret = $node->safe_psql('postgres',
	"set extension_control_path = ''; select count(*) > 0 as ok from pg_available_extensions where name = 'plpgsql'"
);
is($ret, "t",
	"\$system extension is installed correctly on pg_available_extensions with empty extension_control_path"
);

# Test with an extension that does not exists
my ($code, $stdout, $stderr) =
  $node->psql('postgres', "CREATE EXTENSION invalid");
is($code, 3, 'error to create an extension that does not exists');
like($stderr, qr/ERROR:  extension "invalid" is not available/);

sub create_extension
{
	my ($ext_name, $ext_dir, $directory) = @_;

	my $control_file = "$ext_dir/extension/$ext_name.control";
	my $sql_file;

	if (defined $directory)
	{
		$sql_file = "$ext_dir/$directory/$ext_name--1.0.sql";
	}
	else
	{
		$sql_file = "$ext_dir/extension/$ext_name--1.0.sql";
	}

	# Create .control .sql file
	open my $cf, '>', $control_file
	  or die "Could not create control file: $!";
	print $cf "comment = 'Test extension_control_path'\n";
	print $cf "default_version = '1.0'\n";
	print $cf "relocatable = true\n";
	print $cf "directory = $directory" if defined $directory;
	close $cf;

	# Create --1.0.sql file
	open my $sqlf, '>', $sql_file or die "Could not create sql file: $!";
	print $sqlf "/* $sql_file */\n";
	print $sqlf
	  "-- complain if script is sourced in psql, rather than via CREATE EXTENSION\n";
	print $sqlf
	  qq'\\echo Use "CREATE EXTENSION $ext_name" to load this file. \\quit\n';
	close $sqlf;
}

done_testing();
