#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use lib "$FindBin::Bin/lib";
use OptArgs2;
use Data::Dumper;

$Data::Dumper::Indent   = 1;
$Data::Dumper::Sortkeys = 1;

cmd demo => (
    comment => 'OptArgs2 demonstration script',
    optargs => sub {

        arg command => (
            isa      => 'SubCmd',
            comment  => '',
            required => 1,
            abbrev   => 1,
        );

        opt help => ( ishelp => 1 );

        opt usage_tree => (
            isa     => 'Flag',
            comment => 'display usage tree and exit',
            alias   => 'u',
            hidden  => 1,
            trigger => sub { die shift->usage_tree },
        );
    },
);

subcmd 'demo::arg' => (
    comment => 'arguments',
    optargs => sub {

        arg type => (
            isa      => 'SubCmd',
            comment  => 'arg type',
            required => 1,
        );
    },
);

subcmd 'demo::arg::arrayref' => (
    comment => 'ArrayRef argument',
    optargs => sub {

        arg aaa => (
            isa      => 'ArrayRef',
            comment  => 'isa: ArrayRef, name: aaa',
            required => 1,
        );
    },
);

subcmd 'demo::arg::greedy' => (
    comment => 'arguments',
    optargs => sub {

        arg type => (
            isa      => 'SubCmd',
            comment  => 'arg type',
            required => 1,
        );
    },
);

subcmd 'demo::arg::greedy::arrayref' => (
    comment => 'ArrayRef argument',
    optargs => sub {

        arg aaa => (
            isa      => 'ArrayRef',
            comment  => 'isa: ArrayRef, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'ArrayRef',
            comment => 'isa: ArrayRef, name: bbb',
            default => [],
            greedy  => 1,
        );
    },
);

subcmd 'demo::arg::greedy::hashref' => (
    comment => 'HashRef argument',
    optargs => sub {

        arg aaa => (
            isa      => 'HashRef',
            comment  => 'isa: HashRef, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'HashRef',
            comment => 'isa: HashRef, name: bbb',
            greedy  => 1,
        );
    },

);

subcmd 'demo::arg::greedy::str' => (
    comment => 'Str argument',
    optargs => sub {

        arg aaa => (
            isa      => 'Str',
            comment  => 'isa: Str, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'Str',
            comment => 'isa: Str, name: bbb',
            default => 'some text',
            greedy  => 1,
        );
    },
);

subcmd 'demo::arg::hashref' => (
    comment => 'HashRef argument',
    optargs => sub {

        arg aaa => (
            isa      => 'HashRef',
            comment  => 'isa: HashRef, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'HashRef',
            comment => 'isa: HashRef, name: bbb',
            default => { x => 1 },

        );
    },
);

subcmd 'demo::arg::int' => (
    comment => 'Int argument',
    optargs => sub {

        arg aaa => (
            isa      => 'Int',
            comment  => 'isa: Int, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'Int',
            comment => 'isa: Int, name: bbb',
            default => 5,

        );
    },
);

subcmd 'demo::arg::num' => (
    comment => 'Num argument',
    optargs => sub {

        arg aaa => (
            isa      => 'Num',
            comment  => 'isa: Num, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'Num',
            comment => 'isa: Num, name: bbb',
            default => 6,

        );
    },
);

subcmd 'demo::arg::str' => (
    comment => 'Str argument',
    optargs => sub {

        arg aaa => (
            isa      => 'Str',
            comment  => 'isa: Str, name: aaa',
            required => 1,
        );

        arg bbb => (
            isa     => 'Str',
            comment => 'isa: Str, name: bbb',
            default => 'some text',

        );
    },
);

#    required => undef,
#    default  => undef,
#    greedy   => undef,
#    fallback => undef,

subcmd 'demo::opt' => (
    comment => 'options',
    optargs => sub {

        opt req => (
            alias    => 'r',
            isa      => 'Flag',
            comment  => 'isa: Flag, name: req',
            required => 1,
        );

        opt arrayref => (
            isa     => 'ArrayRef',
            comment => 'isa: ArrayRef, name: arrayref',
            alias   => 'a',
        );

        opt bool => (
            isa     => 'Bool',
            comment => 'isa: Bool, name: bool',
            alias   => 'a',
        );

        opt bool_default_0 => (
            isa     => 'Bool',
            comment => 'isa: Bool, name: bool_default_0',
            default => 0,
            alias   => 'b',
        );

        opt bool_default_1 => (
            isa     => 'Bool',
            comment => 'isa: Bool, name: bool_default_1',
            default => 1,
            alias   => 'c',
        );

        opt counter => (
            isa     => 'Counter',
            comment => 'isa: Counter, name: counter',
            alias   => 'a',
        );

        opt counter_default_3 => (
            isa     => 'Counter',
            comment => 'isa: Counter, name: counter_default_3',
            default => -3,
            alias   => 'b',
        );

        opt flag => (
            isa     => 'Flag',
            comment => 'isa: Flag, name: flag',
            alias   => 'a',
        );

        opt no_flag => (
            isa     => 'Flag',
            comment => 'isa: Flag, name: no_flag',
            alias   => 'b',
        );

        opt hashref => (
            isa     => 'HashRef',
            comment => 'isa: HashRef, name: hashref',
            alias   => 'a',
        );

        opt hashref_default => (
            isa     => 'HashRef',
            comment => 'isa: HashRef, name: hashref_default',
            default => { x => 1 },
            alias   => 'b',
        );

        opt int => (
            isa     => 'Int',
            comment => 'isa: Int, name: int',
            alias   => 'a',
        );

        opt int_default => (
            isa     => 'Int',
            comment => 'isa: Int, name: int_default',
            default => 5,
            alias   => 'b',
        );

        opt num => (
            isa     => 'Num',
            comment => 'isa: Num, name: num',
            alias   => 'a',
        );

        opt num_default => (
            isa     => 'Num',
            comment => 'isa: Num, name: num_default',
            default => 6,
            alias   => 'b',
        );

        opt str => (
            isa     => 'Str',
            comment => 'isa: Str, name: str',
            alias   => 'a',
        );

        opt str_default => (
            isa     => 'Str',
            comment => 'isa: Str, name: str_default',
            default => 'some text',
            alias   => 'b',
        );

        opt isa_name => (
            isa      => 'Str',
            isa_name => 'XXX',
            comment  => 'isa: Str, name: isa_name',
            alias    => 'b',
        );
    },
);

my ( $cmd, $opts ) = eval { class_optargs('demo') };
my $err = $@;
my $ref = ref $err;
die "$err\n$ref\n" if $ref;
die $err           if $err;

print Dumper( bless $opts, $cmd );
