
=pod

=head1 NAME $RCSfile: JIRA.pm,v $

Minimal module to talk to JIRA and get a few fields

=head1 VERSION

=over

=item Author

Andrew DeFaria <Andrew.DeFaria@WebPros.com>

=item Revision

$Revision: 1.0 $

=item Created

Monday, April 25 2022

=item Modified

Monday, April 25 2022

=back

=cut

package JIRA;

use strict;
use warnings;

use feature 'say';
use experimental qw(signatures);

use Display;
use Carp;

use JIRA::REST;

my %findQuery;

sub new ( $class, %opts ) {
    croak "JIRA::new: Username not specified" unless $opts{username};
    croak "JIRA::new: Password not specified" unless $opts{password};
    croak "JIRA::new: Server not specified"   unless $opts{server};

=pod

=head2 new ()

Create a new JIRA object connecting to the JIRA database

Parameters:

=for html <blockquote>

=over

=item $opts{username}

Username to authenticate with

=item $opts{password}

Password to authenticate with

=item $opts{server}

JIRA server to connect to

=back

=for html </blockquote>

Returns:

=for html <blockquote>

=over

=item $jira

JIRA Object

=back

=for html </blockquote>

=cut

    $opts{URL} = "http://$opts{server}/rest/api/latest";

    $opts{rest} = JIRA::REST->new( $opts{URL}, $opts{username}, $opts{password} );

    return bless \%opts, $class;
}

sub findIssues ( $self, $condition, @fields ) {

=pod

=head2 findIssues ()

Set up a find for JIRA issues based on a condition

Parameters:

=for html <blockquote>

=over

=item $condition

Condition to use. JQL is supported

=item @fields

List of fields to retrieve data for

=back

=for html </blockquote>

Returns:

=for html <blockquote>

=over

=item <nothing>

=back

=for html </blockquote>

=cut

    push @fields, '*all' unless @fields;

    $findQuery{jql}        = $condition || '';
    $findQuery{startAt}    = 0;
    $findQuery{maxResults} = 1;
    $findQuery{fields}     = join ',', @fields;

    return;
}    # findIssues

sub getNextIssue ($self) {
    my $result;

=pod

=head2 getNextIssue ()

Get next qualifying issue. Call findIssues first

Parameters:

=for html <blockquote>

=over

=item <none>

=back

=for html </blockquote>

Returns:

=for html <blockquote>

=over

=item %issue

Perl hash of the fields in the next JIRA issue

=back

=for html </blockquote>

=cut

    eval { $result = $self->{rest}->GET( '/search/', \%findQuery ) };

    $findQuery{startAt}++;

    # Move id and key into fields
    return unless @{ $result->{issues} };

    $result->{issues}[0]{fields}{id}  = $result->{issues}[0]{id};
    $result->{issues}[0]{fields}{key} = $result->{issues}[0]{key};

    return %{ $result->{issues}[0]{fields} };
}    # getNextIssue

sub getIssues ( $self, $condition, $start, $max, @fields ) {

=pod

=head2 getIssues ()

Get the @fields of JIRA issues based on a condition. Note that JIRA limits the
amount of entries returned to 1000. You can get fewer. Or you can use $start
to continue from where you've left off. 

Parameters:

=for html <blockquote>

=over

=item $condition

JQL condition to apply

=item $start

Starting point to get issues from

=item $max

Max number of entrist to get

=item @fields

List of fields to retrieve

=back

=for html </blockquote>

Returns:

=for html <blockquote>

=over

=item @issues

Perl array of hashes of JIRA issue records

=back

=for html </blockquote>

=cut

    push @fields, '*all' unless @fields;

    my ( $result, %query );

    $query{jql}        = $condition || '';
    $query{startAt}    = $start     || 0;
    $query{maxResults} = $max       || 50;
    $query{fields}     = join ',', @fields;

    eval { $result = $self->{rest}->GET( '/search/', \%query ) };

    # We sometimes get an error here when $result->{issues} is undef.
    # I suspect this is when the number of issues just happens to be
    # an even number like on a $query{maxResults} boundry. So when
    # $result->{issues} is undef we assume it's the last of the issues.
    # (I should really verify this).
    if ( $result->{issues} ) {
        return @{ $result->{issues} };
    }
    else {
        return;
    }    # if
}    # getIssues

sub getIssue ( $self, $issue, @fields ) {

=pod

=head2 getIssue ()

Get individual JIRA issue

Parameters:

=for html <blockquote>

=over

=item $issue

Issue ID

=item @fields

List of fields to retrieve

=back

=for html </blockquote>

Returns:

=for html <blockquote>

=over

=item %issue

Perl hash of JIRA issue

=back

=for html </blockquote>

=cut

    my $fields = @fields ? "?fields=" . join ',', @fields : '';

    return $self->{rest}->GET("/issue/$issue$fields");
}    # getIssue

1;
