#!perl

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

=head1 NAME

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

=head1 VERSION

0.1.0

=cut

sub version {
	print "cape_utils v. 0.1.0\n";
	exit 255;
}

=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>] [B<--json>] [B<--quiet>] <file/dir> [<file/dir...]

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

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

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

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

cape_utils -a eve [B<-c> <config>]=head1 Action: submit

cape_utils -a munge [B<-c> <config>] B<-r> <report json>

=head1 GENERAL FLAGS

=head2 --c <ini>

Config INI file.

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

=head2 -a <action>

Action to perform.

=head2 ---json

Output the result of searches or submissions as JSON.

=head1 ACTIONS

=head2 submit

=head3 @ARGS

Files/dirs to submit.

=head3 --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

=head3  --timeout <timeout

Timeout value in seconds.

Default :: 200

=head3 --machine <machine>

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

Default :: undef

=head3 --package <package>

Package to use, if not letting CAPE decide.

Default :: undef

=head3 --options <opts>

Option string to be passed via --options.

Default :: undef

=head3 --tags <tags>

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

Default :: undef

=head3 --enforce_timeout

Force it to run the entire period.

=head3 --unique

Only submit unique items.

=head3 --quiet

Do not print the output from the submission command.

=head2 running

=head3 -C

Print the running count instead of the table.

=head3 -w <where>

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

=head2 pending

=head3 -C

Print the pending count instead of the table.

=head3 -w <where>

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

=head2 tasks

=head3 -C

Print the running count instead of the table.

=head3 --direction <dir>

Direction to order in, desc or asc.

Default :: desc

=head3 --order <column>

Column to order by.

Default :: id

=head3 -w <where>

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

=head2 fail

=head3 -w <where>

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

=head2 eve

Invoke CAPE::Utils->process_eve.

=head2 munge

=head3 -r <report json>

The report JSON to munge.

=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

sub help {
	pod2usage( -exitval => 255, -verbose => 2, -output => \*STDOUT, );
} ## end sub help

# 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;
my $quiet;
my $report_json;
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,
	'r=s'             => \$report_json,
	'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,
	'quiet'           => \$quiet,
);

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 );
		}
	} ## end else [ if ($count) ]
	exit 0;
} ## end if ( $action eq 'pending' )

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 );
		}
	} ## end else [ if ($count) ]
	exit 0;
} ## end if ( $action eq 'running' )

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
			);
		}
	} ## end else [ if ($count) ]
	exit 0;
} ## end if ( $action eq 'tasks' )

if ( $action eq 'submit' ) {
	if ($use_json) {
		$quiet = 1;
	}
	my $results = $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,
		quiet           => $quiet,
	);
	if ($use_json) {
		my $j = JSON->new;
		if ($pretty) {
			$j->pretty(1);
		}
		print $j->encode($results);
		if ( !$pretty ) {
			print "\n";
		}
	} ## end if ($use_json)

	exit 0;
} ## end if ( $action eq 'submit' )

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

if ( $action eq 'eve' ) {
	$cape_utils->eve_process();
	exit 0;
}

if ( $action eq 'munge' ) {
	if ( !defined($report_json) ) {
		die('No report JSON specified via -r');
	}

	$cape_utils->munge( file => $report_json );
	exit 0;
}

die 'No action for -a matched';
