#!perl

=head1 NAME

cape_utils - A utility to help with various basic tasks related to CAPEv2.

=head1 SYNOPSIS

cape_utils -a submit [B<-c> <config>] [B<--clock> <time>] [B<--timeout> <seconds>] [B<--machine> <machine>]
[B<--package> <package>] [B<--options> <options>] [B<--tags> <tags>] [B<--enforce_timeout>]
[B<--unique>] <file/dir> [<file/dir...]

cape_utils -a running [B<-c> <config>] [B<-C>] [B<-w> <where>]

cape_utils -a pending [B<-c> <config>] [B<-C>] [B<-w> <where>]

cape_utils -a tasks [B<-c> <config>] [B<-C>] [B<-w> <where>] [B<--direction> <dir>] [B<--order> <column>]

cape_utils -a fail [B<-c> <config>] B<-w> <where>

=head1 GENERAL FLAGS

=head2 -c <ini>

Config INI file.

Default: /usr/local/etc/cape_utils.ini

=head2 -a <action>

Action to perform.

=head1 Action: submit

=head2 @ARGS

Files/dirs to submit.

=head2 --clock <time>

Timestamp to use for setting the clock to of the VM for
when executing the item. If left undefined, it will be
autogenerated.

Format :: mm-dd-yyy HH:MM:ss

=head2  --timeout <timeout

Timeout value in seconds.

Default :: 200

=head2 --machine <machine>

The machine to use for this. If not defined,
first available will be used.

Default :: undef

=head2 --package <package>

Package to use, if not letting CAPE decide.

Default :: undef

=head2 --options <opts>

Option string to be passed via --options.

Default :: undef

=head2 --tags <tags>

Tags to be passed to the script via --tags.

Default :: undef

=head2 --enforce_timeout

Force it to run the entire period.

=head2 --unique

Only submit unique items.

=head1 Action: running

=head2 -C

Print the running count instead of the table.

=head2 -w <where>

Additional SQL args for use with statement for
getting running items.

=head1 Action: pending

=head2 -C

Print the pending count instead of the table.

=head2 -w <where>

Additional SQL args for use with statement for
getting pending items.

=head1 Action: tasks

=head2 -C

Print the running count instead of the table.

=head2 --direction <dir>

Direction to order in, desc or asc.

Default :: desc

=head2 --order <column>

Column to order by.

Default :: id

=head2 -w <where>

Additional SQL args for use with statement for
getting running items.

=head1 Action: fail

=head2 -w <where>

Additional SQL args for use with statement for
failing pending items.

=head1 CONFIG FILE

For this, see the docs for CAPE::Utils.

Out of the box, it will work by default with CAPEv2 in it's default config.

=cut

use CAPE::Utils;
use strict;
use warnings;
use Getopt::Long;
use JSON;

sub version {
	print "cape_utils v. 0.0.1\n";
}

sub help {
	&version;

	print '
-c <ini>     Config INI file.
             Default: /usr/local/etc/cape_utils.ini

-a <action>  Action to perform.

Action Specific Args...

Action: submit

@ARGS                  Files/dirs to submit.

--clock <time>         Timestamp to use for setting the clock to of the VM for
                       when executing the item. If left undefined, it will be
                       autogenerated.
                       Format :: mm-dd-yyy HH:MM:ss

--timeout <timeout>    Timeout value in seconds.
                       Default :: 200

--machine <machine>    The machine to use for this. If not defined, first
                       available will be used.
                       Default :: undef

--package <package>    Package to use, if not letting CAPE decide.
                       Default :: undef

--options <opts>       Option string to be passed via --options.
                       Default :: undef

--tags <tags>          Tags to be passed to the script via --tags.
                       Default :: undef

--enforce_timeout      Force it to run the entire period.

--unique               Only submit unique items.


Action: running

-C                     Print the running count instead of the table.

-w <where>             Additional SQL args for use with statement for
                       getting running items.

Action: pending

-C                     Print the pending count instead of the table.

-w <where>             Additional SQL args for use with statement for
                       getting pending items.


Action: tasks

-C                     Print the running count instead of the table.

--direction <dir>      Direction to order in, desc or asc.
                       Default :: desc

--order <column>       Column to order by.
                       Default :: id

-w <where>             Additional SQL args for use with statement for
                       getting running items.


Action: fail

-w <where>             Additional SQL args for use with statement for
                       failing pending items.
';
}

# get the commandline options
my $help    = 0;
my $version = 0;
my $ini_file;
my $action;
my $count;
my $use_json;
my $where;
my $clock;
my $timeout;
my $machine;
my $package;
my $options;
my $random = 1;
my $tags;
my $platform;
my $enforce_timeout;
my $custom;
my $unique;
my $limit;
my $order;
my $direction;
my $pretty;
Getopt::Long::Configure('no_ignore_case');
Getopt::Long::Configure('bundling');
GetOptions(
	'version'         => \$version,
	'v'               => \$version,
	'help'            => \$help,
	'h'               => \$help,
	'i=s'             => \$ini_file,
	'a=s'             => \$action,
	'C'               => \$count,
	'w=s'             => \$where,
	'clock=s'         => \$clock,
	'timeout=i'       => \$timeout,
	'machine=s'       => \$machine,
	'package=s'       => \$package,
	'options=s'       => \$options,
	'random=i'        => \$random,
	'tags=s'          => \$tags,
	'platform=s'      => \$tags,
	'et'              => \$enforce_timeout,
	'enforce_timeout' => \$enforce_timeout,
	'custom'          => \$custom,
	'unique'          => \$unique,
	'limit=s'         => \$limit,
	'order'           => \$order,
	'direction'       => \$direction,
	'json'            => \$use_json,
	'pretty'          => \$pretty,
);

if ($version) {
	&version;
	exit 255;
}

if ($help) {
	&help;
	exit 255;
}

my $cape_utils = CAPE::Utils->new($ini_file);

if ( !defined($action) ) {
	print "No action specified via -a\n";
	exit 1;
}

if ( $action eq 'pending' ) {
	if ($count) {
		print $cape_utils->get_pending_count( where => $where ) . "\n";
	}
	else {
		if ($use_json) {
			my $items = $cape_utils->get_pending( where => $where );
			my $j     = JSON->new;
			if ($pretty) {
				$j->pretty(1);
			}
			print $j->encode($items);
			if ( !$pretty ) {
				print "\n";
			}
		}
		else {
			print $cape_utils->get_pending_table( where => $where );
		}
	}
	exit 0;
}

if ( $action eq 'running' ) {
	if ($count) {
		print $cape_utils->get_running_count( where => $where ) . "\n";
	}
	else {
		if ($use_json) {
			my $items = $cape_utils->get_running( where => $where );
			my $j     = JSON->new;
			if ($pretty) {
				$j->pretty(1);
			}
			print $j->encode($items);
			if ( !$pretty ) {
				print "\n";
			}
		}
		else {
			print $cape_utils->get_running_table( where => $where );
		}
	}
	exit 0;
}

if ( $action eq 'tasks' ) {
	if ($count) {
		print $cape_utils->get_tasks_count( where => $where ) . "\n";
	}
	else {
		if ($use_json) {
			my $items = $cape_utils->get_tasks(
				where => $where,

				order     => $order,
				where     => $where,
				direction => $direction
			);
			my $j = JSON->new;
			if ($pretty) {
				$j->pretty(1);
			}
			print $j->encode($items);
			if ( !$pretty ) {
				print "\n";
			}
		}
		else {
			print $cape_utils->get_tasks_table(
				limit     => $limit,
				order     => $order,
				where     => $where,
				direction => $direction
			);
		}
	}
	exit 0;
}

if ( $action eq 'submit' ) {
	$cape_utils->submit(
		items           => \@ARGV,
		clock           => $clock,
		timeout         => $timeout,
		machine         => $machine,
		package         => $package,
		options         => $options,
		random          => $random,
		tags            => $tags,
		enforce_timeout => $enforce_timeout,
		unique          => $unique,
	);
	exit 0;
}

if ( $action eq 'fail' ) {
	print $cape_utils->fail( where => $where );
	exit 0;
}

die 'No action for -a matched';
