use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.

# various variables...

# places to look for libraries in
my (@trylib) = (
		"/usr/athena/lib",
		"/usr/kerberos/lib",
		"/usr/local/lib",
		"/usr/lib",
		);

# how many times a particular library directory was searched...
my (@foundlib) = ();

# places to look for includes in
my (@tryinc) = (
		"/usr/athena/include",
		"/usr/athena/include/kerberosIV",
		"/usr/local/include",
		"/usr/local/include/kerberosIV",
		"/usr/include",
		"/usr/include/kerberosIV",
		"/usr/kerberos/include",
		"/usr/kerberos/include/kerberosIV",
		);
# how many times a particular include directory was searched...
my (@foundinc) = ();

# sets of libraries to search for
my @libs = (
	    [
	     "zephyr",
	     "com_err",
	     "krb4",
	     "des425",
	     "krb5",
	     "crypto",
	     ],
	    [
	     "zephyr",
	     "com_err",
	     "krb",
	     "des",
	     ],
	    );

# headers to search for
my (@headers) = (
		 "zephyr/zephyr.h",
		 "krb_err.h",
		 "com_err.h",
		 );


# error tables to search for
my (@errtab) = (
		"zephyr/zephyr_err.h",
		"krb_err.h",
		);

# defines for the C preprocessor...
my ($defs, @defs);

# ccflags to compile with...
my ($ccflags, @ccflags);

# -L flags and -l flags to pass to the linker
my ($libdirs, $libs);

# -I flags to pass to the preprocessor
my ($incdirs, @incdirs);

# error table filenames
my ($errfiles, @errfiles);

# Various subroutines...

# process an argument
sub proc_args {
    my ($arg) = @_;

    if ($arg =~ /^-L(.*)/) {
	push @trylib, $1;
    } elsif ($arg =~ /^-l(.*)/) {
	unshift @trylib, $1;
    } elsif ($arg =~ /^-I(.*)/) {
	push @tryinc, $1;
    } elsif ($arg =~ /^-i(.*)/) {
	unshift @tryinc, $1;
    } elsif ($arg =~ /^(-D.*)/) {
	push @defs, $1;
    } elsif ($arg eq "-d") {
	push @defs, "-DPZEPHYR_DEBUG";
    } elsif ($arg =~ /^-c(.*)/) {
	push @ccflags, '-' . $1;
    } else {
	return 0;
    }
    return 1;
}

# flush @foundlib...
sub init_lib {
    for (my $i = 0; $i <= $#trylib; $i++) {
	$foundlib[$i] = 0;
    }
}

# flush @foundinc...
sub init_inc {
    for (my $i = 0; $i <= $#tryinc; $i++) {
	$foundinc[$i] = 0;
    }
}

# find a library somewhere in @trylib...
sub find_lib {
    my ($lib) = @_;
    my ($dirent);

    print "Looking for $lib...";

    for (my $i = 0; $i <= $#trylib; $i++) {
	next
	    if (!-d $trylib[$i]);

	next
	    if (!opendir(LIBDIR, $trylib[$i]));

	while (defined($dirent = readdir(LIBDIR))) {
	    if ($dirent =~ m!lib$lib\.(a|so)[^/]*!) {
		print "found (in $trylib[$i])\n";
		$foundlib[$i]++;
		closedir(LIBDIR);
		return 1;
	    }
	}
	closedir(LIBDIR);
    }

    print "not found\n";

    return 0;
}

# find a header somewhere in @tryinc
sub find_inc {
    my ($header) = @_;

    print "Looking for $header...";

    for (my $i = 0; $i <= $#tryinc; $i++) {
	if (-r "$tryinc[$i]/$header") {
	    print "found (in $tryinc[$i])\n";
	    $foundinc[$i]++;
	    return 1;
	}
    }

    print "not found\n";

    return 0;
}

# find the error table somewhere in @tryinc
sub find_err {
    my ($errtab) = @_;

    print "Looking for $errtab...";

    for (my $i = 0; $i <= $#tryinc; $i++) {
	if (-r "$tryinc[$i]/$errtab") {
	    print "found (in $tryinc[$i])\n";
	    return "$tryinc[$i]/$errtab";
	}
    }

    print "not found\n";

    return undef;
}

# the core stuff...

# turn off buffering...
$| = 1;

shift @ARGV
    while (defined($ARGV[0]) && &proc_args($ARGV[0]));

LIB_LOOP:
    for (my $i = 0; $i <= $#libs; $i++) {
	my ($alib);
	my (@libdirs);
	my (@tmplibs);

	print "Searching libset $i...\n";

	&init_lib(); # initialize @foundinc...

	foreach $alib (@{$libs[$i]}) {
	    next LIB_LOOP
		if (!&find_lib($alib)); # try to find the library...
	}

	# all libs were successfully found; build -L flags
	for (my $j = 0; $j <= $#trylib; $j++) {
	    push @libdirs, '-L' . $trylib[$j]
		if ($foundlib[$j]);
	}
	$libdirs = join " ", @libdirs;

	# build -l flags...
	foreach $alib (@{$libs[$i]}) {
	    push @tmplibs, '-l' . $alib;
	}
	$libs = join " ", @tmplibs;

	last; # break out of the loop
    }

# did we find enough libraries?
die "Unable to find necessary libraries"
    if (!defined($libdirs));

# tell the user about it...
print "Using libdirs $libdirs\n";
print "Using libraries $libs\n";

&init_inc(); # initialize @foundinc

for (my $i = 0; $i <= $#headers; $i++) {
    die "Unable to find necessary header file"
	if (!&find_inc($headers[$i])); # look for the headers...
}

# build -I flags for the preprocessor...
for (my $i = 0; $i <= $#tryinc; $i++) {
    push @incdirs, '-I' . $tryinc[$i]
	if ($foundinc[$i]);
}
$incdirs = join " ", @incdirs;

# tell the user about it...
print "Using incdirs $incdirs\n";

# lookup error tables...
for (my $i = 0; $i <= $#errtab; $i++) {
    my ($tmp);

    die "Unable to find necessary error table"
	if (!defined($tmp = &find_err($errtab[$i], @incdirs))); # find it

    push @errfiles, $tmp;
}
$errfiles = join " ", @errfiles;

# tell the user what the error tables are
print "Using error tables $errfiles\n";

# put together the -D flags
$defs = join " ", @defs;

# and tell the user about them
print "Using defines $defs\n";

# put together the CCFLAGS
$ccflags = join " ", @ccflags;

# and tell the user about them
print "Using CCFLAGS $ccflags\n";

# finally, write the make file
WriteMakefile('NAME'		=> "Zephyr",
	      'DISTNAME'	=> "pZephyr",
	      'VERSION_FROM'	=> "Zephyr.pm",
	      'INSTALLDIRS'	=> "perl",
	      'PM'		=> {
		  'Zephyr.pm'	=> '$(INST_LIBDIR)/Zephyr.pm',
		  'Notice.pm'	=> '$(INST_LIBDIR)/Zephyr/Notice.pm',
	      },
	      'LIBS'		=> [ "$libdirs $libs" ],
	      'DEFINE'		=> "$defs",
	      'CCFLAGS'		=> "$ccflags",
	      'OPTIMIZE'	=> "-g -O",
	      'INC'		=> "$incdirs",
	      'OBJECT'		=> "Zephyr.o get_symbol.o",
	      'EXE_FILES'	=> [ 'zwrite.pl' ],
	      'MAN3PODS'	=> {
		  "Zephyr.pm"	=> '$(INST_MAN3DIR)/Zephyr.3',
		  'Notice.pm'	=> '$(INST_MAN3DIR)/Zephyr::Notice.3',
	      },
	      'clean'		=> {
		  'FILES'	=> "symbols.def",
	      },
	      'depend'		=> {
		  'get_symbol.o'=> "symbols.def",
		  'get_symbol'	=> "symbols.def",
	      },
	      'dist'		=> {
		  'TARFLAGS'	=> "cvf",
		  'COMPRESS'	=> "gzip",
		  'SUFFIX'	=> ".gz",
	      },
	      'macro'		=> {
		  'ERROR_TABLES'=> "$errfiles",
	      },
	      );

sub MY::postamble {
    '
symbols.def: symbols.def.pl
	$(PERL) symbols.def.pl $(ERROR_TABLES)
';
}
