#!perl
#
#This software is Copyright (c) 2025 by Zane C. Bowers-Hadley.
#
#This is free software, licensed under:
#
#  The Artistic License 2.0 (GPL Compatible)

use strict;
use warnings;
use TOML            qw(from_toml);
use File::Syslogger ();
use File::Slurp     qw(read_file);
use Getopt::Long    qw( GetOptions );
use Pod::Usage      qw(pod2usage);

my $version = '0.0.1';

sub main::VERSION_MESSAGE {
	print 'filesyslogger v. ' . $File::Syslogger::VERSION . "\n";
	exit 255;
}

sub main::HELP_MESSAGE {
	pod2usage( -exitval => 255, -verbose => 2, -output => \*STDOUT, );
}

my $help_flag;
my $toml_file = '/usr/local/etc/filesyslogger.toml';
my $pri;
my $fac;
my $socket;
my $program;
my $version_flag;
Getopt::Long::Configure('no_ignore_case');
Getopt::Long::Configure('bundling');
GetOptions(
	'c=s'     => \$toml_file,
	'h'       => \$help_flag,
	'help'    => \$help_flag,
	'v'       => \$version_flag,
	'version' => \$version_flag,
);

if ($version_flag) {
	main::VERSION_MESSAGE;
	exit 255;
}

if ($help_flag) {
	main::HELP_MESSAGE;
	exit 255;
}

# make sure the file exists
if ( !-f $toml_file ) {
	die( '"' . $toml_file . '" does not exist' );
}

# read the in or die
my $toml_raw = read_file($toml_file) or die 'Failed to read "' . $toml_file . '"';

# read the specified config
my ( $toml, $err ) = from_toml($toml_raw);
unless ($toml) {
	die "Error parsing toml,'" . $toml_file . "'" . $err;
}

# read in the defaults, letting the switches over ride
if ( defined( $toml->{program} ) ) {
	$program = $toml->{program};
}
if ( defined( $toml->{'facility'} ) ) {
	$fac = $toml->{facility};
}
if ( defined( $toml->{priority} ) ) {
	$pri = $toml->{priority};
}
if ( defined( $toml->{socket} ) ) {
	$socket = $toml->{socket};
}

# process the config
my %files;
my @toml_keys = keys( %{$toml} );
my $int       = 0;
while ( defined( $toml_keys[$int] ) ) {
	my $item = $toml_keys[$int];

	if ( ref( $toml->{$item} ) eq "HASH" ) {

		# add the file in question
		$files{$item} = $toml->{$item};
	}

	$int++;
} ## end while ( defined( $toml_keys[$int] ) )

File::Syslogger->run(
	facility => $fac,
	pri      => $pri,
	socket   => $socket,
	files    => \%files,
);

=head1 NAME

filesyslogger - Tails the configured files and sends it to syslog.

=head1 SYNOPSIS

filesyslogger [B<-c> <config>]

=head1 FLAGS

=head2 -c <config file>

This is the config file to use. If not specified, '/usr/local/etc/filesyslogger.toml' is used.

=head1 CONFIG FILE

The file format used is TOML.

The primary and optional keys are as below.

    - priority :: The priority of the logged item.
          Default :: notice

    - facility :: The facility for logging.
          Default :: daemon

    - program :: Name of the program logging.
          Default :: fileSyslogger

    - socket :: The syslogd socket.
        Default :: /var/run/log


Each file defined in a TOML table. `priority`, `facility`, and `program`
can be used like above.

    - file :: The file to follow. This must be specified
        Default :: undef

Each TOML table is used for specifying what files to tail
and forward to syslog. It uses the same keys as above, minus
'socket', but with the additional key 'file' for specifying
what file.

File rotation is picked up automatically via POE::Wheel::FollowTail.

For priority, below are the various valid values.

    emerg
    emergency
    alert
    crit
    critical
    err
    error
    warning
    notice
    info

For facility, below are the various valid values.

    kern
    user
    mail
    daemon
    auth
    syslog
    lpr
    news
    uucp
    cron
    authpriv
    ftp
    local0
    local1
    local2
    local3
    local4
    local5
    local6
    local7

=head1 EXAMPLE

    facility="daemon"
    priority="alert"
    socket="/var/run/log"
    [sagan]
    program="saganEve"
    file="/var/log/sagan/eve"
    [suricata]
    program="suricataEve"
    file="/var/log/suricata/eve"

=cut
