package Palm::Zetetic::Strip;

use strict;
use Palm::PDB;
use Palm::Zetetic::Strip::PDB::ParserFactory;

require Exporter;

use vars qw(@ISA $VERSION);

@ISA = qw(Exporter);
$VERSION = "1.02";

=head1 NAME

Palm::Zetetic::Strip - Manipulate Zetetic Strip Palm database files

=head1 SYNOPSIS

  use Palm::Zetetic::Strip;

  $strip = new Palm::Zetetic::Strip('directory_to_pdb_files/');
  if (! $strip->set_password('strip_password'))
  {
      print "Incorrect password\n";
      exit(1);
  }

  $strip->load();
  @systems = $strip->get_systems();
  @accounts = $strip->get_accounts($systems[0]);

=head1 DESCRIPTION

The Palm::Zetetic::Strip module provides access to database files
generated by the Strip (Secuure Tool for Recalling Important
Passwords) from Zetetic.

=head1 METHODS

=head2 new

  $strip = new Palm::Zetetic::Strip($pdb_directory);

Creates a new Palm::Zetetic::Strip object.  The directory provided
must contain the .pdb files.

=cut

sub new
{
    my $class = shift;
    my $self = {};

    bless $self, $class;

    $self->{systems}    = [];
    $self->{accounts}   = [];
    $self->{password}   = "";
    $self->{directory}  = "";
    $self->{parser_factory} = new Palm::Zetetic::Strip::PDB::ParserFactory;

    return $self;
}

=head2 set_password

  $success = set_password('plaintext password');

Sets the password to unlock the databases.  Return true if the
password is correct, otherwise false.

=cut

sub set_password
{
    my ($self, $password) = @_;
    if ($self->verify_password($password))
    {
        $self->{password} = $password;
        return 1;
    }
    else
    {
        return 0;
    }
}

=head2 load

  $strip->load()

Loads the system and accounts databases into memory.

=cut

sub load
{
    my ($self) = @_;

    $self->load_systems();
    $self->load_accounts();
}

=head2 get_systems

  @systems = $strip->get_systems();

Returns an array of Palm::Zetetic::Strip::System objects.

=cut

sub get_systems
{
    my ($self) = @_;
    my @systems;

    @systems = values(%{$self->{systems}});
    @systems = sort {$a->get_name() cmp $b->get_name()} @systems;
    return @systems;
}

sub get_system_name
{
    my ($self, $system_id) = @_;
    my $system;

    $system = $self->{systems}->{$system_id};
    return $system->get_name();
}

=head2 get_accounts

  @accounts = $strip->get_accounts();

Returns an array of Palm::Zetetic::Strip::Account objects.

=cut

sub get_accounts
{
    my ($self, $system) = @_;
    my $accounts;

    $accounts = $self->{accounts}->{$system->get_id()};
    $accounts = [] if (! defined($accounts));
    return @$accounts;
}

#
# All private methods go here
#

sub verify_password
{
    my ($self, $password) = @_;
    my $password_pdb_file;
    my $password_pdb_parser;

    $password_pdb_file = $self->get_password_pdb_file();
    $password_pdb_parser = $self->{parser_factory}->get_password_parser();
    $password_pdb_parser->load($password_pdb_file);
    return $password_pdb_parser->verify_password($password);
}

sub get_strip_version
{
    my ($self) = @_;
    return $self->{parser_factory}->get_strip_version();
}

sub set_directory
{
    my ($self, $directory, $version) = @_;
    my $parser_factory;

    $parser_factory = $self->{parser_factory};
    if (defined $version)
    {
        $parser_factory->set_strip_version($version);
    }
    else
    {
        $parser_factory->set_strip_version_autodetect($directory);
    }

    $self->{directory} = $directory;
}

sub get_password_pdb_file
{
    my ($self) = @_;
    return $self->{directory} . "/StripPassword-SJLO.pdb";
}

sub get_systems_pdb_file
{
    my ($self) = @_;
    return $self->{directory} . "/StripSystems-SJLO.pdb";
}

sub get_accounts_pdb_file
{
    my ($self) = @_;
    return $self->{directory} . "/StripAccounts-SJLO.pdb";
}

sub load_systems
{
    my ($self) = @_;
    my $systems_pdb_file;
    my $systems_pdb_parser;
    my $systems;
    my $system;

    $systems_pdb_file = $self->get_systems_pdb_file();
    $systems_pdb_parser = $self->{parser_factory}->get_systems_parser();
    $systems_pdb_parser->load($systems_pdb_file);
    $self->{systems} = {};
    $systems = $systems_pdb_parser->get_systems($self->{password});

    foreach $system (@$systems)
    {
        $self->{systems}->{$system->get_id()} = $system;
    }

    return;
}

sub load_accounts
{
    my ($self) = @_;
    my $accounts_pdb_file;
    my $accounts_pdb_parser;
    my $accounts;
    my $account;
    my $system_accounts;

    $accounts_pdb_file = $self->get_accounts_pdb_file();
    $accounts_pdb_parser = $self->{parser_factory}->get_accounts_parser();
    $accounts_pdb_parser->load($accounts_pdb_file);
    $self->{accounts} = {};
    $accounts = $accounts_pdb_parser->get_accounts($self->{password});

    foreach $account (@$accounts)
    {
        if (! defined($self->{accounts}->{$account->get_system_id()}))
        {
            $self->{accounts}->{$account->get_system_id()} = [];
        }
        $system_accounts = $self->{accounts}->{$account->get_system_id()};
        push(@$system_accounts, $account);
    }

    return;
}

1;

__END__

=head1 FILES

F<StripPassword-SJLO.pdb> - Password database.

F<StripSystems-SJLO.pdb> - Systems database.

F<StripAccounts-SJLO.pdb> - Accounts database.

=head1 SEE ALSO

Palm::Zetetic::Strip::System(3), Palm::Zetetic::Strip::Account(3)

=head1 AUTHOR

Dave Dribin