package Judy;

use strict;
use warnings;
use vars qw( $VERSION $DEBUG $HANDLE);
use base qw(DynaLoader);

$VERSION = '0.41';

sub _libjudy_candidates {
    # Get a list of possible libJudy.so files.
    #
    # When writing this module, I found it would occasionally not only
    # find libJudy.so but also blib/arch/Judy/Judy.so which is the
    # Perl XS module. That was when this -lJudy resolving code was
    # directly in the Judy cpan module though which has a lib/Judy.xs
    # file. It's plausible that it's entirely irrelevant now that this
    # is in Alien::Judy.
    #
    my @candidate_libs = DynaLoader::dl_findfile('-lJudy');
    if ( $DEBUG ) {
        printf STDERR "candidates=@candidate_libs at %s line %d.\n", __FILE__, __LINE__;
    }

    # I found that Solaris would find libJudy.so with DynaLoader but
    # ld.so.1 when loading libJudy.so for Judy.pm would fail to find
    # the right library to link against.
    #
    # I don't particularly understand it however what worked was to
    # attempt to load libJudy.so.1 first.
    my @dot_one =
        grep { -f }
        map { "$_.1" }
        @candidate_libs;

    unshift @candidate_libs, @dot_one;

    return @candidate_libs;
}

sub _dl_load_libjudy {
    my @candidate_libs = @_;

    # The libJudy I find must provide the base functions from the
    # libJudy library. This is to possibly skip "wrong" libJudy
    # libraries.
#    @DynaLoader::dl_require_symbols = 'Judy1Test';

    # Attempt to load each candidate until something succeeds. If one
    # of the candidates happens to be the Perl XS module
    # blib/arch/Judy/Judy.so then I'd like loading to keep trying and
    # not fail. If I know how to predictably filter
    # blib/arch/Judy/Judy.so out of this list I'd do that.
    my $libjudy_loaded;
  CANDIDATE_LIBRARY:
    for my $libjudy_file ( @candidate_libs ) {
        my $ok = eval {
            $HANDLE = DynaLoader::dl_load_file( $libjudy_file, 0x01 );
            1;
        };
        if ( $DEBUG ) {
            my $msgf =
                $ok
                ? "Loaded $libjudy_file at %s line %d.\n"
                : "Couldn't load $libjudy_file: $@ at %s line %d.\n";
            printf STDERR $msgf, __FILE__, __LINE__;
        }

        if ( $ok ) {
            $libjudy_loaded = 1;
            last CANDIDATE_LIBRARY;
        }
    }

    return $libjudy_loaded;
}

sub dl_load_libjudy {
    #local @DynaLoader::dl_library_path = (
     #   @DynaLoader::dl_library_path,
     #   lib_dirs()
    #);

    # Enable DynaLoader debugging along with Judy debugging
    local $DynaLoader::dl_debug = $DynaLoader::dl_debug;
    if ( $DEBUG ) {
        $DynaLoader::dl_debug ||= 1;
    }

    my @libjudy_files = _libjudy_candidates();

    my $ok = _dl_load_libjudy( @libjudy_files );

    return $ok;
}

__PACKAGE__->bootstrap;

require Sub::Exporter;
Sub::Exporter->import(
    -setup => {
        exports => [qw[ PJERR JLAP_INVALID ]]
    }
);

# Load the OO interfaces.
#
require Judy::_obj;

# Load the tie interface.
# 
require Judy::_tie;
Judy::_tie->import;

# Load the functional interfaces.
require Judy::Mem::_impl;
require Judy::1::_impl;
require Judy::L::_impl;
require Judy::SL::_impl;
require Judy::HS::_impl;

1;
