package MooseX::Workers::ScheduledJob;
use strict;
use Moose;
use Moose::Util::TypeConstraints;
use MooseX::Storage;
use DateTime::Event::ICal;

extends 'MooseX::Workers::Job';
with Storage( 'format' => 'JSON' );

my @ical_attrs = qw(freq dtstart until interval);

for (qw(
        bysecond byminute byhour
        byday bymonthday byyearday
        byweekno bymonth
    )){
        subtype "ICal\u$_"
            => as 'ArrayRef';
        coerce "ICal\u$_"
            => from 'Value'
            => via { [$_] };
        has $_ => (
            is  => 'ro',
            isa => "ICal\u$_",
            coerce => 1,
        );
        push @ical_attrs, $_;
}
subtype 'ICalFrequency'
    => as 'Str',
    => where { $_ =~ /^(year|month|week|dai|hour|minute|second)ly$/ }
    => message {
        "\u$_ is not a valid ICal frequency"
    };
has 'freq' => (
    is  => 'ro',
    isa => 'ICalFrequency',
    required => 1,
);
has 'dtstart' => (
    is  => 'ro',
    isa => 'DateTime',
);
has 'until' => (
    is  => 'ro',
    isa => 'DateTime',
);
has 'interval' => (
    is  => 'ro',
    isa => 'Num',
    default => 1,
);
has 'set' => (
    metaclass => 'DoNotSerialize',
    is        => 'ro',
    isa       => 'DateTime::Set',
    lazy      => 1,
    default   => sub {
        my $self = shift;
        DateTime::Event::ICal->recur(
            map { $_ => $self->$_ }
            grep { defined $self->$_ } 
            @ical_attrs
        );
    },
    handles => [qw/
        next
        previous
        contains
        iterator
        as_list
    /],
);

no Moose;  # unimport Moose's keywords so they won't accidentally become methods
1;         # Magic true value required at end of module
__END__
