package JIRA::REST::Class::Factory;
use base qw( Class::Factory::Enhanced );
use strict;
use warnings;
use v5.10;

our $VERSION = '0.03';

# ABSTRACT: A factory class for building all the other classes in C<JIRA::REST::Class>.

# here is our list of every class this factory knows how to make
#
JIRA::REST::Class::Factory->add_factory_type(
    factory      => 'JIRA::REST::Class::Factory',
    issue        => 'JIRA::REST::Class::Issue',
    changelog    => 'JIRA::REST::Class::Issue::Changelog',
    change       => 'JIRA::REST::Class::Issue::Changelog::Change',
    changeitem   => 'JIRA::REST::Class::Issue::Changelog::Change::Item',
    linktype     => 'JIRA::REST::Class::Issue::LinkType',
    status       => 'JIRA::REST::Class::Issue::Status',
    statuscat    => 'JIRA::REST::Class::Issue::Status::Category',
    timetracking => 'JIRA::REST::Class::Issue::TimeTracking',
    transitions  => 'JIRA::REST::Class::Issue::Transitions',
    transition   => 'JIRA::REST::Class::Issue::Transitions::Transition',
    issuetype    => 'JIRA::REST::Class::Issue::Type',
    worklog      => 'JIRA::REST::Class::Issue::Worklog',
    workitem     => 'JIRA::REST::Class::Issue::Worklog::Item',
    project      => 'JIRA::REST::Class::Project',
    projectcat   => 'JIRA::REST::Class::Project::Category',
    projectcomp  => 'JIRA::REST::Class::Project::Component',
    projectvers  => 'JIRA::REST::Class::Project::Version',
    iterator     => 'JIRA::REST::Class::Iterator',
    sprint       => 'JIRA::REST::Class::Sprint',
    query        => 'JIRA::REST::Class::Query',
    user         => 'JIRA::REST::Class::User',
);

use Carp;
use DateTime::Format::Strptime;

#pod =internal_method B<init>
#pod
#pod Initialize the factory object.  Just copies all the elements in the hashref that were passed in to the object itself.
#pod
#pod =cut

sub init {
    my $self = shift;
    my $args = shift;
    my @keys = keys %$args;
    @{$self}{@keys} = @{$args}{@keys};
    return $self;
}

#pod =internal_method B<make_object>
#pod
#pod A tweaked version of the object creator from C<Class::Factory::Enhanced> that calls C<init()> with a copy of the factory.
#pod
#pod =cut

sub make_object {
    my ($self, $object_type, @args) = @_;
    my $class = $self->get_factory_class($object_type);
    my $obj = $class->new(@args);
    $obj->init($self); # make sure we pass the factory into init()
    return $obj;
}

#pod =internal_method B<make_date>
#pod
#pod Make it easy to get C<DateTime> objects from the factory.
#pod
#pod =cut

sub make_date {
    my ($self, $date) = @_;
    return unless $date;
    state $parser = DateTime::Format::Strptime->new( pattern => '%FT%T.%N%Z' );
    return $parser->parse_datetime($date);
}

#pod =internal_method B<factory_error>
#pod
#pod Throws errors from the factory with stack traces
#pod
#pod =cut

sub factory_error {
    my $class = shift;
    my $err   = shift;
    # start the stacktrace where we called make_object()
    local $Carp::CarpLevel = $Carp::CarpLevel+2;
    confess "$err\n", @_;
}

1;

__END__

=pod

=encoding UTF-8

=for :stopwords Packy Anderson Alexey Melezhik

=head1 NAME

JIRA::REST::Class::Factory - A factory class for building all the other classes in C<JIRA::REST::Class>.

=head1 VERSION

version 0.03

=head1 INTERNAL METHODS

=head2 B<init>

Initialize the factory object.  Just copies all the elements in the hashref that were passed in to the object itself.

=head2 B<make_object>

A tweaked version of the object creator from C<Class::Factory::Enhanced> that calls C<init()> with a copy of the factory.

=head2 B<make_date>

Make it easy to get C<DateTime> objects from the factory.

=head2 B<factory_error>

Throws errors from the factory with stack traces

=head1 AUTHOR

Packy Anderson <packy@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2016 by Packy Anderson.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

=cut
