package App::POS::MessageQueue;

use Time::HiRes qw( usleep );
use JSON;
use Data::Dumper;
use App::POS::Utils qw(
  memcache
);

sub new {
  my $class = shift;
  my %args = @_;

  #RECEIVES IP ADRESS AND NAMESPACE

  my $self = bless { %args }, ref($class) || $class;

  $self->{__memd} = memcache($args{server}, $args{name});

  return $self;
}

sub log {
  my $self = shift;
  my $msg = shift;
}

sub send {
  my $self = shift;
  my ($key, $value) = @_;

  $self->__aquire_lock();

  my $list = $self->{__memd}->get('__list__');
  $list = [] unless defined $list;
  push @$list, $key;

  $self->{__memd}->set($key, $value, 120);
  $self->{__memd}->set('__list__', $list, 120);

  $self->log("ADDING $key\n");

  $self->log(Dumper $list);

  $self->__release_lock();
}

sub get {
  my $self = shift;
  my ($key) = @_;

  $self->__aquire_lock();

  my $msg = $self->{__memd}->get($key);

  $self->__release_lock();

  return $msg;
}

sub remove {
  my $self = shift;
  my ($key) = @_;

  $self->__aquire_lock();

  my $list = $self->{__memd}->get('__list__');
  $list = [] unless defined $list;

  $self->log("REMOVING ".$key."\n");

  my $i = 0;
  foreach my $msg (@{$list}) {
    if ($msg eq $key) {
      splice(@$list, $i, 1);
      last;
    }
    $i++;
  }

  $self->log(Dumper $list);

  my $msg = $self->{__memd}->get($key);
  $self->{__memd}->set('__list__', $list, 120);

  $self->__release_lock();

  return $msg;
}

sub list {
  my $self = shift;

  $self->__aquire_lock();

  my $list = $self->{__memd}->get('__list__') || [];

  $self->__release_lock();

  return $list;
}

#PRIVATE METHODS

sub __aquire_lock {
  my $self = shift;

  my $total_sleep = 1000000; # 1 SECOND

  while ($total_sleep > 0) {
    my $lock = $self->{__memd}->incr("list-lock",1);
    
    if ($lock == 1) { 
      return;
    }

    $total_sleep -= usleep(1000);
  }

  $self->log("FAILED ALL ATTEMPTS $total_sleep\n");

  if ($total_sleep <= 0) {
    $self->{__memd}->set("list-lock", 0, 120);
  }
}

sub __release_lock {
  my $self = shift;

  $self->{__memd}->set("list-lock",0, 120);
}


1;
