package IO::Iron::IronCache::Item;

## no critic (Documentation::RequirePodAtEnd)
## no critic (Documentation::RequirePodSections)
## no critic (Subroutines::RequireArgUnpacking)

use 5.010_000;
use strict;
use warnings;

# Global creator
BEGIN {
	# No exports
}

# Global destructor
END {
}


# ABSTRACT: IronCache (Online Item-Value Storage) Client (Cache Item).

our $VERSION = '0.12_01'; # TRIAL VERSION: generated by DZP::OurPkgVersion



use Log::Any  qw($log);
use Hash::Util 0.06 qw{lock_keys unlock_keys};
use Carp::Assert::More;
use English '-no_match_vars';
use Params::Validate qw(:all);

# CONSTANTS for this module

# DEFAULTS


sub new {
	my $class = shift;
	my %params = validate(
		@_, {
			'value' => { type => SCALAR, },        # Item value (free text), mandatory, can be empty.
			'expires_in' => { type => SCALAR, optional => 1, },   # How long in seconds to keep the item in the cache before it is deleted.
            'expires' => { type => SCALAR, optional => 1, },      # When will the item be deleted. This is a date string.
            # TODO Add expires into docs!
			'replace' => { type => SCALAR, optional => 1, },      # Only set the item if the item is already in the cache.
			'add' => { type => SCALAR, optional => 1, },          # Only set the item if the item is not already in the cache.
			'cas' => { type => SCALAR, optional => 1, },          # Cas value can only be set when the item is read from the cache.
		}
	);
	$log->tracef('Entering new(%s, %s)', $class, %params);
	my $self;
	my @self_keys = ( ## no critic (CodeLayout::ProhibitQuotedWordLists)
			'value',        # Item value (free text), can be empty.
			'expires_in',   # How long in seconds to keep the item in the cache before it is deleted.
            'expires',      # When will the item be deleted. This is a date string.
			'replace',      # Only set the item if the item is already in the cache.
			'add',          # Only set the item if the item is not already in the cache.
			'cas',          # Cas value can only be set when the item is read from the cache.
	);
	lock_keys(%{$self}, @self_keys);
	$self->{'value'} = defined $params{'value'} ? $params{'value'} : undef;
	$self->{'expires_in'} = defined $params{'expires_in'} ? $params{'expires_in'} : undef;
    $self->{'expires'} = defined $params{'expires'} ? $params{'expires'} : undef;
	$self->{'replace'} = defined $params{'replace'} ? $params{'replace'} : undef;
	$self->{'add'} = defined $params{'add'} ? $params{'add'} : undef;
	$self->{'cas'} = defined $params{'cas'} ? $params{'cas'} : undef;
	# All of the above can be undefined, except the value.
	assert_defined( $self->{'value'}, 'self->{value} is defined and is not blank.' );
	# If timeout, add or expires_in are undefined, the IronMQ defaults (at the server) will be used.

	unlock_keys(%{$self});
	my $blessed_ref = bless $self, $class;
	lock_keys(%{$self}, @self_keys);

	$log->tracef('Exiting new: %s', $blessed_ref);
	return $blessed_ref;
}


sub value { return $_[0]->_access_internal('value', $_[1]); }
sub expires_in { return $_[0]->_access_internal('expires_in', $_[1]); }
sub expires { return $_[0]->_access_internal('expires', $_[1]); }
sub replace { return $_[0]->_access_internal('replace', $_[1]); }
sub add { return $_[0]->_access_internal('add', $_[1]); }
sub cas { return $_[0]->_access_internal('cas', $_[1]); }

# TODO Move _access_internal() to IO::Iron::Common.

sub _access_internal {
	my ($self, $var_name, $var_value) = @_;
	$log->tracef('_access_internal(%s, %s)', $var_name, $var_value);
	if( defined $var_value ) {
		$self->{$var_name} = $var_value;
		return $self;
	}
	else {
		return $self->{$var_name};
	}
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

IO::Iron::IronCache::Item - IronCache (Online Item-Value Storage) Client (Cache Item).

=head1 VERSION

version 0.12_01

=head1 SYNOPSIS

Please see IO::Iron::IronCache::Client for usage.

=for stopwords IronCache Params IronHTTPCallException Mikko Koivunalho timestamp cas Cas

=head1 REQUIREMENTS

=head1 SUBROUTINES/METHODS

=head2 new

Creator function.

=head2 Getters/setters

Set or get a property.
When setting, returns the reference to the object.

=over 8

=item value        Item value (free text), can be empty.

=item expires_in   How long in seconds to keep the item in the cache before it is deleted.

=item expires      Time of expiration as a timestamp.

=item replace      Only set the item if the item is already in the cache.

=item add          Only set the item if the item is not already in the cache.

=item cas          Cas value can only be set when the item is read from the cache.

=back

=head1 AUTHOR

Mikko Koivunalho <mikko.koivunalho@iki.fi>

=head1 BUGS

Please report any bugs or feature requests to bug-io-iron@rt.cpan.org or through the web interface at:
 http://rt.cpan.org/Public/Dist/Display.html?Name=IO-Iron

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2017 by Mikko Koivunalho.

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

The full text of the license can be found in the
F<LICENSE> file included with this distribution.

=cut
