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

package KoLBot::FileStateManager;
 
# Copyright (c) 2004 Alan W. Mahoney. All rights reserved. 
# This program is free software.  You may modify and/or 
# distribute it under the same terms as Perl itself.  
# This copyright notice must remain attached to the file.  
#
# Forms a base class for an in-memory state manager.  Eventually
# there should be versions of this for relational DB or flat-file
# interfaces

# 15 July 2004

use warnings;
use strict;

use Carp;
use Storable qw( lock_store lock_retrieve );

use Fcntl qw( :DEFAULT :flock);

use KoLBot::StateManager;

BEGIN 
{
  use Exporter ();
  our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $ID);

  $VERSION     = 0.5;
  $ID          = '$Id: FileStateManager.pm 2 2004-11-29 00:47:38Z alan $';

  @ISA         = qw(Exporter KoLBot::StateManager);
  @EXPORT      = qw();
  %EXPORT_TAGS = ( );

  @EXPORT_OK   = qw();
}

our @EXPORT_OK;

##########################################
## element access
##########################################

for my $field (qw( 
		   config
		   )) {
  no strict "refs";
  *$field = sub {
    my $self = shift;
    $self->{$field} = shift if @_;
    return $self->{$field};
  }
}

##########################################
## Constructor:
##########################################

sub new {
  my $invocant = shift;
  my $class = ref($invocant) || $invocant;
  my $sm = { 
		  @_ };
  confess "no path" unless $sm->{config}->{path};
  $sm->{config}->{path} =~ m|/$|
    or $sm->{config}->{path} .= '/';
  bless $sm, $class;
}

##########################################
## The rest
##########################################

sub set {
  my $sm = shift;
  my $user = lc(shift);
  my $property = shift;
  my $value = shift;

  confess "no path" unless $sm->{config}->{path};
  my $file = $sm->{config}->{path}.$user.'.'.$property;

  if(defined($value)) {
    defined(lock_store $value,$file) or croak;
  } else {
    # I think this is the way to delete a file...
    open(FH, "<",$file) 
      and flock(FH,LOCK_EX)
      and unlink $file;
    close FH;
  }
}

sub get {
  my $sm = shift;
  my $user = lc(shift);
  my $property = shift;

  confess "no path" unless $sm->{config}->{path};
  my $file = $sm->{config}->{path}.$user.'.'.$property;

  # AWM: Whoops, could disappear between -e and retrieve
  if(-e $file) {
    my $ret = lock_retrieve($file);
    defined($ret) or croak;
    return $ret;
  }
  return {};
}
  

END {} ;

1;

