#!/usr/bin/env perl
package main;

## Author : Joshua S. Day (haxmeister)
## Purpose : An anonymous funtoo data reporting tool
## With code from: Palica, Tom Ryder and ShadowM00n
##
## written with the following additional packages
##
## from funtoo repository:
## dev-perl/JSON-2.900.0
##
## also from Github
## The accompanying "Report.pm" module

use 5.014;
use strict;                                     #core
use warnings;                                   #core
use English qw(-no_match_vars);                 #core
use Getopt::Long qw(:config no_ignore_case);    #core
use JSON;                                       #cpan
use Funtoo::Report;                             #GIT
use HTTP::Tiny;                                 #core
use Pod::Usage;                                 #core

our $VERSION = '3.2.2';

my %es_config = (
    node  => 'https://es.host.funtoo.org:9200',
    index => Funtoo::Report::report_time('short'),
    type  => 'report',
);

# parse options
if ( !@ARGV ) {
    pod2usage();
}
my $debug = 0;
GetOptions(
    'config|c=s'      => \$Funtoo::Report::config_file,
    'update-config|u' => \my $update_config,
    'list-config|l'   => \my $list_config,
    'show-json|j'     => \my $show_json,
    'send|s'          => \my $send,
    'verbose|v'       => sub { $Funtoo::Report::VERBOSE = 1 },
    'debug|d'         => \$debug,
    'help|h'          => \&pod2usage,
    'version|V'       => sub {
        printf "funtoo-report: %s\nFuntoo::Report: %s\n", $VERSION,
            Funtoo::Report::version();
        exit;
    },
) or pod2usage;

if (@ARGV) {
    pod2usage();
}

# Handle options
if ($update_config) {
    Funtoo::Report::update_config();
}

if ($list_config) {
    my %config = Funtoo::Report::user_config();
    print "Current configuration of $Funtoo::Report::config_file:\n\n";
    for my $key ( sort keys %config ) {
        print "$key: $config{$key}\n";
    }
}

if ($show_json) {

    # get the entire report
    my %report = report_from_config();

    # generate a json object that we can use to convert to json
    my $json = JSON->new->allow_nonref;

    # send the report to the json object to be encoded to json
    # and print the results with proper indents (pretty)
    my $json_pretty = $json->pretty->encode( \%report );
    print $json_pretty;
}

if ($send) {

    # get the entire report
    my %report = report_from_config();
    Funtoo::Report::send_report( \%report, \%es_config, $debug );
}

## let's read the config file and generate the report
sub report_from_config {
    my %config = Funtoo::Report::user_config();  # fetch/parse the user config
    my %hash;

    # look for a UUID in the config file and
    # if it's not there, add one
    if ( exists $config{'UUID'} ) {
        $es_config{'id'} = $config{'UUID'};
    }
    else {
        $es_config{'id'} = Funtoo::Report::add_uuid();
    }

    # let's load a hash with the possible config file options as keys
    # and the values will be a pointer to the function that generates
    # the associated information
    my %sections = (
        'boot-dir-info'  => \&Funtoo::Report::get_boot_dir_info,
        'kernel-info'    => \&Funtoo::Report::get_kernel_info,
        'kit-info'       => \&Funtoo::Report::get_kit_info,
        'profile-info'   => \&Funtoo::Report::get_profile_info,
        'installed-pkgs' => \&Funtoo::Report::get_all_installed_pkg,
        'hardware-info'  => \&Funtoo::Report::get_hardware_info,

    );

    # check each key and see if it's in the config file
    for my $report ( sort keys %sections ) {
        exists $config{$report} or next;

        # does the key have a 'y' in the config?
        $config{$report} eq 'y' or next;

        # if so, call the function and add the returned
        # hash table to the report
        $hash{$report} = $sections{$report}->();
    }

    ## adding UUID to the body of the report
    #
    $hash{'funtoo-report'}{'UUID'} = $config{'UUID'};

    ## adding timestamp to report
    #
    $hash{'timestamp'} = Funtoo::Report::report_time('long');

    ## adding version number to report
    #
    $hash{'funtoo-report'}{'version'} = Funtoo::Report::version();

    ## adding any non fatal errors to the report
    #
    $hash{'funtoo-report'}{'errors'} = Funtoo::Report::errors();

    ## adding timers to report
    $hash{'execution-timers'} = Funtoo::Report::timer();

    return %hash;
}

__END__

=pod

=head1 NAME

funtoo-report - An anonymous Funtoo data reporting tool

=head1 USAGE

    funtoo-report
    -c, --config        Specify path to config file
    -u, --update-config Interactively updates the config file
    -l, --list-config   Lists the current configuration file's settings
    -j, --show-json     Shows the JSON report
    -s, --send          Sends the JSON report
    -d, --debug         Enables additional debug output
    -v, --verbose       Enables non-error output when sending
    -h, --help          Display this help text
    -V, --version       Prints the version and exits

=head1 DESCRIPTION

This script is the frontend to C<Funtoo::Report>, allowing you to create
configuration files and generate full report data in JSON to view and submit to
the ElasticSearch servers.

=head1 REQUIRED ARGUMENTS

--send for the intended purpose; all others are strictly optional.

=head1 OPTIONS

=over 4

=item C<-c>, C<--config>

Specify the path to the configuration file; the default path is
C</etc/funtoo-report.conf>.

=item C<-u>, C<--update-config>

Generate or update the configuration file. Files created this way will include
a comment with a timestamp and the version of funtoo-report the file was
created for.

=item C<-l>, C<--list-config>

List the current configuration file's settings. This is primarily a
troubleshooting aid to ensure that variables are being assigned correctly and
will exclude any comments present in the configuration file.

=item C<-j>, C<--show-json>

Generate the system report according to the configuration file and print it to
standard output.

=item C<-s>, C<--send>

Generate the system report and send it to the hardcoded ElasticSearch server.
See also the C<--verbose> option.

=item C<-d>, C<--debug>

Enable debugging mode. At present, this only prints the JSON response from the
ElasticSearch server with the C<--send> option.

=item C<-v>, C<--verbose>

Enables non-error output when sending. At present, this only prints the report
URL from the ElasticSearch server with the C<--send> option.

=item C<-h>, C<--help>

Print usage information.

=item C<-V>, C<--version>

Print script and module versions.

=back

=head1 DIAGNOSTICS

This section to be completed. The code (well, its module) emits very many error
messages that should hopefully be at least partly self-explanatory.

=head1 EXIT STATUS

This front-end exits successfully unless the options provided don't make sense.
Errors with the reporting module will generate their own specific exit codes.

=head1 CONFIGURATION

The configuration file is required and can be generated with the
C<--update-config> option (recommended). The default path is
C</etc/funtoo-report.conf>, but an alternative path can be specified with the
C<--config> option.

=head1 DEPENDENCIES

=over 4

=item *

Perl v5.14.0 or newer

=item *

L<English>

=item *

L<Funtoo::Report>

=item *

L<Getopt::Long>

=item *

L<HTTP::Tiny>

=item *

L<JSON>

=item *

L<Pod::Usage>

=back

=head1 INCOMPATIBILITIES

This script is almost certainly only useful on a Funtoo computer.

=head1 BUGS AND LIMITATIONS

Definitely. To report bugs or make feature requests, please raise an issue on
GitHub at L<https://github.com/haxmeister/funtoo-reporter>.

=head1 AUTHOR

The Funtoo::Report development team:

=over 4

=item *

Joshua Day C<< <haxmeister@hotmail.com> >>

=item *

Palica C<< <palica@cupka.name> >>

=item *

ShadowM00n C<< <shadowm00n@airmail.cc> >>

=item *

Tom Ryder C<< <tom@sanctum.geek.nz> >>

=back

=head1 LICENSE AND COPYRIGHT

MIT License

Copyright (c) 2018 Haxmeister

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

=cut
