#!/usr/bin/perl
x
use warnings;
use strict;
use Getopt::Std;
use vars qw/ $opt_c $opt_n $opt_o $opt_t $opt_h $opt_v $opt_x $opt_z /;
use Config::Tiny;
use File::Spec;

use FTN::Database qw(&open_ftndb &close_ftndb);

$Getopt::Std::STANDARD_HELP_VERSION = 1;

=head1 NAME

listftndb - List information from an Fidonet/FTN SQL database

=head1 VERSION

Version 0.15

=cut

our $VERSION = 0.15;

=head1 DESCRIPTION

List information from a Fidonet/FTN St. Louis Format Nodelist to a text file.
One such listing can be from a specific net from a specific zone of a nodelist table.

=head1 SYNOPSIS

C<listftndb -c config_file [-t tablename] [-z zone] [-n net] [-o outfile] [-v]>

C<listftndb [-h | --help]>

C<listftndb --version>

=cut

my ( $config_file, $db_type, $db_name, $db_user, $db_password, $table_name, $db_handle, $sql_statement, $zone_number, $net_number, $list_file );

getopts('c:n:o:t:hvxz:');

if ($opt_h) {
    HELP_MESSAGE(*STDOUT);
    exit;
}

=head1 OPTIONS

=over

=item -c

This is the filename and path of a configuration file, with the
default being ftnpldb.cfg in the current directory.

=cut

if ($opt_c) {
    $config_file = $opt_c;
    undef $opt_c;
}
else {
    my $config_dir = File::Spec->curdir();
    $config_file = File::Spec->join($config_dir, 'ftnpldb.cfg');
}

#  Get configuration from file
my $ftndb_config = Config::Tiny->new();
$ftndb_config = Config::Tiny->read($config_file)
    or die "Could not open configuration file:  $config_file";

=item -x

Debug option.

=cut

if ($opt_x) {
    print "Debug flag is set\n";
}

=item -v

Verbose option.

=cut

if ($opt_v) {
    print "Verbose flag is set\n";
}

# Get the definition of the database type
$db_type = $ftndb_config->{Database}->{Type};	

if ($opt_v) { print "Database type being used is $db_type\n" };

# Get the definition of the database name
$db_name = $ftndb_config->{Database}->{Name};

if ($opt_v) { print "Database name being used is $db_name\n" };

# Get the definition of the database user
if ($db_type eq "SQLite") {

    $db_user = "";

} else {
    $db_user = $ftndb_config->{Database}->{User};

    if ($opt_v) { print "Database user being used is $db_user\n" };

}

# Get the definition of the database password
if ($db_type eq "SQLite") {

    $db_password = ""; 

} else {

    $db_password = $ftndb_config->{Database}->{Password};
    if ($opt_v) { print "Database password being used is $db_password\n" };

}

=item -t

The nodelist table name to be used.
Note that if there is a period in the name, that period will be changed
to an underscore.

=cut

if ($opt_t) {
    if ( $opt_t =~ /\./ ) {    # period in proposed table name?
        print "sqlite does not allow periods in table names.";
        $opt_t=~ tr/\./_/;    # change period to underscore
        $table_name = $opt_t;     #
        print "Changed table name to $table_name.";
    }
    else {                     # no period in name
        $table_name = $opt_t;     #  just assign to variable
    }

}
else {
    $table_name = "Nodelist";     # default table name
}

=item -z

If set;  is the FTN Zone number, with 1 being the default.

=cut

if ($opt_z) {
    $zone_number = $opt_z;    # Set zone number 
    undef $opt_z;
}
else {
    $zone_number = 1;    # default zone number
}

=item -n

If set;  is the FTN Net number, with 1 being the default.

=cut

if ($opt_n) {
    $net_number = $opt_n;
    undef $opt_n;
}
else {
    $net_number = 1;
}

=item -o

Output file.
This needs to be at least the filename and can also include a path.
The default output file is outfile.txt in the current directory.

=back

=cut

if ($opt_o) {
    $list_file = $opt_o;    # 
    undef $opt_o;
}
else {
    $list_file = "outfile.txt"; 
}


# connect to database
$db_handle = FTN::Database::open_ftndb($db_type, $db_name, $db_user, $db_password);

# build Select query sql statement
$sql_statement = "SELECT * FROM $table_name WHERE zone = $zone_number and net = $net_number ";
$sql_statement .= "ORDER by node ASC";

# execute query
my $query_handle = $db_handle->prepare($sql_statement);
$query_handle->execute();

$query_handle->bind_columns(\my($id, $type, $zone, $net, $node, $point, $region, $name, $location, $sysop, $phone, $baud, $flags, $domain, $source, $updated));

local(*F);

open(F, ">$list_file") or die "Cannot open $list_file\n"; 

print F "Listing Zone $zone_number Net $net_number from FTN database:\n\n";

while($query_handle->fetch()) {
   print F "$zone:$net/$node, $name, $location, $sysop, $phone, $baud, $flags";
}

close(F);

# finish query
$query_handle->finish;
undef $query_handle;

# disconnect from database
FTN::Database::close_ftndb($db_handle);

exit();

########################################################################
# subroutines
########################################################################
# Display Help message
########################################################################
sub HELP_MESSAGE {

    my $fh = shift;

    print $fh "\n\tUsage:\nlistftndb -c config_file [-t tablename] [-z zone] [-n net] [-o outfile] [-v] [-h | --help] [--version]\n";
    print $fh "\t[-c config_file]\t= Name and path for configuration file.\n";
    print $fh "\t[-t tablename]\t\t= Nodelist table name;  defaults to \'Nodelist\'. \n";
    print $fh "\t[-z zone_number]\t= Zone number number;  defaults to 1.\n";
    print $fh "\t[-n net_number]\t\t= Net number; defaults to 1.\n";
    print $fh "\t[-o outfile]\t\t= Output file (plus path) = defaults to outfile.txt in current directory.\n";
    print $fh "\t[-v]\t\t\t= Verbose option \n";
    print $fh "\t[-x]\t\t\t= Debug option \n";
    print $fh "\t[-h | --help]\t\t= Print this help message \n";
    print $fh "\t[--version]\t\t= Display version message \n\n";

    return();

}

########################################################################
# Display Version message
########################################################################
sub VERSION_MESSAGE {

    my $fh = shift;
    
    print $fh "listftndb version $VERSION\n";

    return();

}

########################################################################

=head1 CONFIGURATION

The B<Database> section in the configuration file has the following
keywords:

=over 4

=item Type

Database type.
This needs to be a database type for which a DBD module exists, the type
being the name as used in the DBD module.  The default type is SQLite.

=item Name

Database name.
For an SQLite databse; this needs to be at least the filename and can
also include a path.

=item User

Database user.
For an SQLite database, this defaults to an empty string as it is not
needed for that type of database.

=item Password

Database password.
For an SQLite database, this defaults to an empty string as it is not
needed for that type of database.

=back

This is an example of the contents of an ftnpldb.cfg file:

    [Database]
    Type=mysql
    Name=ftndbtst
    User=sysop
    Password=ftndbtst

=head1 EXAMPLES

Given that $CFGFILE is a configuration file and that $LISTFILE is a
file where the information is to be listed, the following command line
can be used to list the nodes in Net 102 of Zone 1 in that file:

C<listftndb -c $CFGFILE -z 1 -n 102 -o $LISTFILE -v>

=head1 AUTHOR

Robert James Clay, C<< <jame at rocasa.us> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-ftn-database at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=FTN-Database>.  I will
be notified, and then you'll automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc listftndb


You can also look for information at:

=over 4

=item * RT: CPAN's request tracker

L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=FTN-Database>

=item * AnnoCPAN: Annotated CPAN documentation

L<http://annocpan.org/dist/FTN-Database>

=item * Search CPAN

L<http://search.cpan.org/dist/FTN-Database>

=back

=head1 SEE ALSO

 L<FTN::Database>, L<FTN::Database::Nodelist>, L<ftndbadm>,
 L<ftndbadm>, and L<nl2ftndb>

=head1 COPYRIGHT & LICENSE

Copyright 2010 Robert James Clay, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

