#!perl

use 5.010001;
use strict;
use warnings;

use App::calx;
use DateTime;
use Getopt::Long qw(:config gnu_getopt no_ignore_case);

our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2023-06-22'; # DATE
our $DIST = 'App-calx'; # DIST
our $VERSION = '0.009'; # VERSION

my %args = (
    months => 1,
    caldates_modules => [],
);
my $dates = [];

GetOptions(
    'h'   => sub { $args{highlight_today} = 0 },
    '1'   => sub { $args{months} = 1  },
    '3'   => sub { $args{months} = 3  },
    'y'   => sub { $args{months} = 12 },
    'c=s' => $args{caldates_modules},
    'date=s' => $dates,
    'a'   => sub {
        require Module::List::Tiny;

        my $mods = Module::List::Tiny::list_modules(
            "Calendar::Dates::", {list_modules=>1, recurse=>1});
        my @res = sort keys %$mods;
        for (@res) { s/\ACalendar::Dates::// }
        $args{caldates_modules} = \@res;
    },
);

my $dt = DateTime->now;

my $re = qr/\A((\d{4})-(\d{2})-(\d{2}))(?:\t(.+))?\z/;
if (!(-t STDIN)) { ## no critic: InputOutput::ProhibitInteractiveTest
    my @dates;
    while (my $line = <STDIN>) {
        chomp $line;
        $line =~ $re or die "Invalid date syntax '$line'\n";
        push @dates, {
            date => $1,
            day => $4,
            month => $3,
            year => $2,
            summary => $5,
        };
    }
    $args{dates} = \@dates;
} elsif (@$dates) {
    my @dates;
    for my $date (@$dates) {
        $date =~ $re or die "Invalid date syntax '$date'\n";
        push @dates, {
            date => $1,
            day => $4,
            month => $3,
            year => $2,
            summary => $5,
        };
    }
    $args{dates} = \@dates;
} elsif (@ARGV == 1) {
    $args{year}   = $ARGV[0];
    $args{months} = 12;
} elsif (@ARGV == 2) {
    $args{month} = $ARGV[0];
    $args{year}  = $ARGV[1];
} else {
    $args{month} = $dt->month;
    $args{year}  = $dt->year;
}

if ($args{months} == 3) {
    $dt = DateTime->new(year=>$args{year}, month=>$args{month}//1, day=>1);
    $dt->subtract(months=>1);
    $args{month} = $dt->month;
    $args{year}  = $dt->year;
}

my $res = App::calx::gen_calendar(%args);
die $res->[1] unless $res->[0] == 200;
say $res->[2];

1;
# ABSTRACT: Display calendar, with highlighted dates
# PODNAME: calx

__END__

=pod

=encoding UTF-8

=head1 NAME

calx - Display calendar, with highlighted dates

=head1 VERSION

This document describes version 0.009 of calx (from Perl distribution App-calx), released on 2023-06-22.

=head1 SYNOPSIS

 # show calendar for the current month, with dates from Calendar::Dates::ID::Holiday
 % calx -c ID::Holiday

 # show calendar for the current month, with dates from Calendar::Dates::ID::Holiday and Calendar::Dates::SG::Holiday
 % calx -c ID::Holiday -c SD::Holiday

 # show calendar for the current month, with dates from all installed Calendar::Dates::* modules
 % calx -a

 # show calendar for the whole year
 % calx 2019 -c ID::Holiday

 # show calendar for a certain month and year
 % calx 2 2019 -c ID::Holiday

 # echo -e "2023-05-30\n2023-05-31\n2023-06-01\n" | calx

=head1 DESCRIPTION

This command provides a variant of B<cal> utility for displaying ASCII calendar
on the command-line. It focuses on highlighting certain dates. It currently
always starts the week at Monday and can get the list of dates from command-line
option (`--date`) or stdin or one or more L<Calendar::Dates>::* modules.

=head1 OPTIONS

 % calx [opts] [[month] year]

Most options follow B<cal>. Not all options from B<cal> are
supported/recognized. Some options are specific to B<calx>.

=head2 -1

Show a single month of calendar (the default).

=head2 -3

Show three months of calendar (previous, current, next).

=head2 -h

Turn off highlighting of today.

=head2 -y

Show one year (12 months) of calendar (the default if only year is specified).

=head2 -c MODULE+

Get dates from a L<Calendar::Dates> module (value is name of module without the
"Calendar::Dates::" prefix). Can be specified multiple times.

=head2 -a

Get dates from all installed C<Calendar::Dates::*> modules.

=head2 --date DATE+

Highlight one or more dates. You can also supply the dates from stdin. The dates
must be in ISO8601 C<YYYY-MM-DD> format.

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/App-calx>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-App-calx>.

=head1 SEE ALSO

B<cal> Unix utility

L<Calendar::Dates>

B<cal> Unix utility.

Other B<cal> variants: L<cal-idn> (from L<App::cal::idn>).

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 CONTRIBUTING


To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.

Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:

 % prove -l

If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
that are considered a bug and can be reported to me.

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2023, 2019 by perlancar <perlancar@cpan.org>.

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

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-calx>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=cut
