package OpenSSL::Test::Utils;

use strict;
use warnings;

use Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = "0.1";
@ISA = qw(Exporter);
@EXPORT = qw(alldisabled anydisabled disabled config available_protocols
             have_IPv4 have_IPv6);

=head1 NAME

OpenSSL::Test::Utils - test utility functions

=head1 SYNOPSIS

  use OpenSSL::Test::Utils;

  my @tls = available_protocols("tls");
  my @dtls = available_protocols("dtls");
  alldisabled("dh", "dsa");
  anydisabled("dh", "dsa");

  config("fips");

  have_IPv4();
  have_IPv6();

=head1 DESCRIPTION

This module provides utility functions for the testing framework.

=cut

use OpenSSL::Test qw/:DEFAULT bldtop_file/;

=over 4

=item B<available_protocols STRING>

Returns a list of strings for all the available SSL/TLS versions if
STRING is "tls", or for all the available DTLS versions if STRING is
"dtls".  Otherwise, it returns the empty list.  The strings in the
returned list can be used with B<alldisabled> and B<anydisabled>.

=item B<alldisabled ARRAY>
=item B<anydisabled ARRAY>

In an array context returns an array with each element set to 1 if the
corresponding feature is disabled and 0 otherwise.

In a scalar context, alldisabled returns 1 if all of the features in
ARRAY are disabled, while anydisabled returns 1 if any of them are
disabled.

=item B<config STRING>

Returns an item from the %config hash in \$TOP/configdata.pm.

=item B<have_IPv4>
=item B<have_IPv6>

Return true if IPv4 / IPv6 is possible to use on the current system.

=back

=cut

our %available_protocols;
our %disabled;
our %config;
my $configdata_loaded = 0;

sub load_configdata {
    # We eval it so it doesn't run at compile time of this file.
    # The latter would have bldtop_file() complain that setup() hasn't
    # been run yet.
    my $configdata = bldtop_file("configdata.pm");
    eval { require $configdata;
	   %available_protocols = %configdata::available_protocols;
	   %disabled = %configdata::disabled;
	   %config = %configdata::config;
    };
    $configdata_loaded = 1;
}

# args
#  list of 1s and 0s, coming from check_disabled()
sub anyof {
    my $x = 0;
    foreach (@_) { $x += $_ }
    return $x > 0;
}

# args
#  list of 1s and 0s, coming from check_disabled()
sub allof {
    my $x = 1;
    foreach (@_) { $x *= $_ }
    return $x > 0;
}

# args
#  list of strings, all of them should be names of features
#  that can be disabled.
# returns a list of 1s (if the corresponding feature is disabled)
#  and 0s (if it isn't)
sub check_disabled {
    return map { exists $disabled{lc $_} ? 1 : 0 } @_;
}

# Exported functions #################################################

# args:
#  list of features to check
sub anydisabled {
    load_configdata() unless $configdata_loaded;
    my @ret = check_disabled(@_);
    return @ret if wantarray;
    return anyof(@ret);
}

# args:
#  list of features to check
sub alldisabled {
    load_configdata() unless $configdata_loaded;
    my @ret = check_disabled(@_);
    return @ret if wantarray;
    return allof(@ret);
}

#!!! Kept for backward compatibility
# args:
#  single string
sub disabled {
    anydisabled(@_);
}

sub available_protocols {
    load_configdata() unless $configdata_loaded;
    my $protocol_class = shift;
    if (exists $available_protocols{lc $protocol_class}) {
	return @{$available_protocols{lc $protocol_class}}
    }
    return ();
}

sub config {
    return $config{$_[0]};
}

# IPv4 / IPv6 checker
my $have_IPv4 = -1;
my $have_IPv6 = -1;
my $IP_factory;
sub check_IP {
    my $listenaddress = shift;

    eval {
        require IO::Socket::IP;
        my $s = IO::Socket::IP->new(
            LocalAddr => $listenaddress,
            LocalPort => 0,
            Listen=>1,
            );
        $s or die "\n";
        $s->close();
    };
    if ($@ eq "") {
        return 1;
    }

    eval {
        require IO::Socket::INET6;
        my $s = IO::Socket::INET6->new(
            LocalAddr => $listenaddress,
            LocalPort => 0,
            Listen=>1,
            );
        $s or die "\n";
        $s->close();
    };
    if ($@ eq "") {
        return 1;
    }

    eval {
        require IO::Socket::INET;
        my $s = IO::Socket::INET->new(
            LocalAddr => $listenaddress,
            LocalPort => 0,
            Listen=>1,
            );
        $s or die "\n";
        $s->close();
    };
    if ($@ eq "") {
        return 1;
    }

    return 0;
}

sub have_IPv4 {
    if ($have_IPv4 < 0) {
        $have_IPv4 = check_IP("127.0.0.1");
    }
    return $have_IPv4;
}

sub have_IPv6 {
    if ($have_IPv6 < 0) {
        $have_IPv6 = check_IP("::1");
    }
    return $have_IPv6;
}


=head1 SEE ALSO

L<OpenSSL::Test>

=head1 AUTHORS

Stephen Henson E<lt>steve@openssl.orgE<gt> and
Richard Levitte E<lt>levitte@openssl.orgE<gt>

=cut

1;
