package IO::Iron::IronMQ::Message;

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

use 5.010_000;
use strict;
use warnings;

# Global creator
BEGIN {
}

# Global destructor
END {
}

# ABSTRACT: IronMQ (Online Message Queue) Client (Message).

our $VERSION = '0.14'; # 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(
        @_,
        {
            'body'  => { type => SCALAR, },                            # Message body (free text), can be empty.
            'delay' => { type => SCALAR, optional => 1, }
            ,    # The item will not be available on the queue until this many seconds have passed.
            'push_headers' => { type => HASHREF, optional => 1, },    # Headers for push queues.
            'id' => { type => SCALAR, optional => 1, },    # Message id from IronMQ queue (after message has been reserved/peeked).
            'reserved_count' => { type => SCALAR, optional => 1, },    # FIXME item reserved_count
            'reservation_id' => { type => SCALAR, optional => 1, },    # Reservation id string from the queue.
        }
    );
    $log->tracef( 'Entering new(%s, %s)', $class, %params );
    my $self;
    my @self_keys = (    ## no critic (CodeLayout::ProhibitQuotedWordLists)
        'body',              # Message body (free text), can be empty.
        'delay',             # The item will not be available on the queue until this many seconds have passed.
        'push_headers',      # Push queue headers.
        'id',                # Message id from IronMQ queue (after message has been pulled/peeked).
        'reserved_count',    # FIXME item reserved_count
        'reservation_id',    # reservation_id
    );
    lock_keys( %{$self}, @self_keys );
    $self->{'body'}           = $params{'body'};
    $self->{'delay'}          = defined $params{'delay'}          ? $params{'delay'}          : undef;
    $self->{'push_headers'}   = defined $params{'push_headers'}   ? $params{'push_headers'}   : undef;
    $self->{'id'}             = defined $params{'id'}             ? $params{'id'}             : undef;
    $self->{'reserved_count'} = defined $params{'reserved_count'} ? $params{'reserved_count'} : undef;
    $self->{'reservation_id'} = defined $params{'reservation_id'} ? $params{'reservation_id'} : undef;

    # All of the above can be undefined, except the body: the message can not be empty.
    # If delay is 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 body           { return $_[0]->_access_internal( 'body',           $_[1] ); }
sub delay          { return $_[0]->_access_internal( 'delay',          $_[1] ); }
sub push_headers   { return $_[0]->_access_internal( 'push_headers',   $_[1] ); }
sub id             { return $_[0]->_access_internal( 'id',             $_[1] ); }
sub reserved_count { return $_[0]->_access_internal( 'reserved_count', $_[1] ); }
sub reservation_id { return $_[0]->_access_internal( 'reservation_id', $_[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::IronMQ::Message - IronMQ (Online Message Queue) Client (Message).

=head1 VERSION

version 0.14

=head1 SYNOPSIS

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

=for stopwords IronMQ UNDEF Mikko Koivunalho perldoc CPAN AnnoCPAN tradename

=for stopwords licensable MERCHANTABILITY

=head1 REQUIREMENTS

=head1 SUBROUTINES/METHODS

=head2 new

Creator function.
UNDEF values not accepted.
body is mandatory; delay and push_headers are optional.
id, reserved_count and reservation_id are for internal use.

=head2 Getters/setters

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

=over 8

=item body           Message body (free text), can be empty.

=item delay          The item will not be available on the queue until this many seconds have passed.

=item push_headers   Push queue HTTP headers.

=item id             Message id from IronMQ queue (after message has been pulled/peeked).

=item reserved_count Item reserved count.

=item reservation_id Reservation id string from the queue.

=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) 2023 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
