package OzDB;

use 5.008006;
use strict;
use warnings;
use Benchmark;

# Start the benchmark timer
 my $t0 = new Benchmark;

require Exporter;

our @ISA = qw(Exporter);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use OzDB ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(

          ) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(

);

our $VERSION = '0.1.3';


# methods.
sub new {
# my $t0 = new Benchmark;
    my $package = shift;
    return bless( {}, $package );
# my $t1 = new Benchmark;
# my $td = timediff($t1, $t0);
# print "Your OzDB Request took aproximately ", timestr($td),"\n\nThe results of your request are as follows:\n\n\n";

}

sub verbose {
    my $self = shift;
    if (@_) {
        $self->{'verbose'} = shift;
    }
    return $self->{'verbose'};
}

sub add_user {

# add_user method allows for 4 arguments exactly like authenticate.  The only
# difference is the second argument is ignored, and the third and forth must
# be string and integer respectively.  First argument is the name of the db file
#
# This is a cumulative database.  No remove functionality is implemented.
#
# format, add_user("userfile", "ignored", "user", "authlevel")
# authlevel being numeric value, ignored meaning the arg is not used
     my $self = shift;
     open( USRDB, "<$_[0]" ) or die "error opening user file: $_[0]\n";
    my @lines = <USRDB>;    # Read it into an array
    close(USRDB);
# check for correct syntax
# if ($_[3] !~ /^\d+$/ or $_[2] !~ /^[A-Za-z]+$/)
if (not defined $_[3] or not defined $_[2] or $_[3] !~ /^\d+$/)
  {
   print "The <username> must be letters only and the <auth_lvl> must be a number between 1 and 500\n";
   return "0 $_[2] $_[3]";

  }
  else
     {
     my $test;
        for $test (@lines)
        {
        # skip lines that are comments or blank lines
          if ($test =~ /^s*#/)
          {
            next;
          }
          if ($test =~ /^$/)
          {
            next;
          }
          # still in the for loop
# split the line up into into it's seporate values, delimited by space
          my (@words) = split(/ /, $test);
          # evaluate if the entry exists, if it does, exit the loop and give 'already exists' message
              if ($words[0] eq $_[2])
              {
                  print "The user, $words[0], already exists.\n";
                  return "1 $_[2] $_[3]";

              }
            # ok, the user didn't match, so what do we do now?
            next;
            # go to the next one, duh
            # still looping
           }
        # no longer in loop, but still else
        
        # the entry doesnt exist, lets make one
          print "Adding user $_[2] at authlevel $_[3].\n";

          # re-opening of the file, this time in append mode
          open(USRDB, ">>$_[0]") or die "could not open $_[0] for append!\n";
          # print our data to the file
          print USRDB "$_[2] $_[3]\n";
          # close the file
          close(USRDB);
          return "2 $_[2] $_[3]";

        # still in the else meaning valid syntax with data left to handle
        # open(USRDB, ">>authuser.db");
     }
         # still in the sub, outside the else

 }
 sub add_command {
 return 0;
 }
sub authenticate {

    # format, authenticate("userfile", "commandfile", "user", "command")
    # authlevel being numeric value
    my $self = shift;
    open( USRDB, "<$_[0]" ) or die "error opening user file: $_[0]\n";
    my @users = <USRDB>;    # Read it into an array
    open( CMDDB, "<$_[1]" ) or die "error opening command file: $_[1]\n";
    my @commands = <CMDDB>;
    close(USRDB);
    close(CMDDB);
    my $userset;
    if (not defined $ARGV[0] or not defined $ARGV[1])
    {
    print "Wrong Syntax\n";
    return "0 $_[2] $_[3]";

    }
    for $userset (@users)
    {
        if ( $userset =~ /^s*#/ )
        {
            next;
        }

        if ( $userset =~ /^$/ )
        {
            next;
        }

        my (@userlist) = split( / /, $userset );

        if ( $userlist[0] eq $_[2] )
        {
            my $command;
            for $command (@commands)
            {

                chomp($command);

                if ( $command =~ /^s*#/ )
                {
                    next;
                }
                if ( $command =~ /^$/ )
                {
                    next;
                }
                my (@cmmd) = split( / /, $command );

                if ( $cmmd[0] eq $_[3] )
                {

                    # command exists

                    if ( $userlist[1] >= $cmmd[1] )
                    {
                        if ( defined $cmmd[2] )
                        {
                        # authenticated, but what type of command?
                        if ( $cmmd[2] eq "." )
                        {
                            print "$userlist[0] authenticated for $cmmd[0] which does: @cmmd[3..$#cmmd]\n";
                            return "1.0 $_[2] $_[3] @cmmd[3..$#cmmd]";

                        }

                        else
                        {
                            if ( $cmmd[2] eq "]" )
                           {
                                print "$userlist[0] authenticated for $cmmd[0] which does: @cmmd[3..$#cmmd]\n";
                                 for ( @cmmd[ 3 .. $#cmmd ], $_[2] ) { s/[\x0A\x0D]//g; s/[\r\n]//; }
                                 return "1.1 $_[2] $_[3] @cmmd[3..$#cmmd]";

                                #print "second time @cmmd[3..$#cmmd] test\n";

                            }

                           }
                            }
                            else
                           {
                           {
                             print "$userlist[0] authenticated for $cmmd[0]\n";
                             return "1.2 $_[2] $_[3]";

                            }
                        }
                        # I'm too lazy to track down the iteration of this loop
                        # therefore, I will add this print statement...
                        # If anyone sees the following message, please report
                        # it to the author's email address.
                        print "why did this happen?\n";
                        return "0 $_[2] $_[3]";

                    }
                    print "User $_[2] Not Authenticated\n";
                    return "2 $_[2] $_[3]";

                }

                # looping through the commands
                #print "why did this happen3?\n";
            }
            print "Command $_[3] doesn't exist\n";
            return "3 $_[2] $_[3]";

        }
        next;
        return "0 $_[2] $_[3]";
    }
    print "User $_[2] doesn't exist\n";
    return "4 $_[2] $_[3]";


    #end of sub
}
# see if we can get a different timer result
print "OzDB Driver version $VERSION\n";
# set a stop timer
 my $t1 = new Benchmark;
# calculate time difference
 my $td = timediff($t1, $t0);
 print "Your OzDB Request took aproximately ", timestr($td),"\nThe results of your request are as follows:\n";

1;
__END__

# Below is stub documentation for the module.

=head1 NAME

OzDB - database interface module for OzBot

=head1 SYNOPSIS

use OzDB;


=head1 DESCRIPTION

The OzDB Perl module handles authentication and access control for the OzBot
based utility bots.

=head2 EXPORT

None by default.

=head1 METHODS

=over 4

=item *
$obj->authenticate("authuser.db", "authcmd.db", "$name", "$command");

=item *
$obj->add_user("$authuserdb", "$authcmddb", "$name", "$authlevel");

=back

=head1 SEE ALSO

http://support.linuxops.net

=head1 AUTHOR

NeXeN, aka Osbourne nexen@linuxops.net

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2005 by Daniel Remsburg

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.


=cut
