#!/usr/bin/perl
#
# Copyright (c) 2016-2026, Bill MacAllister <bill@ca-zephyr.org>
# File: ring-load
# Description: queue a picture directory to be loaded into the rings

use strict;
use DBI;
use Getopt::Long;
use File::Find;
use Pod::Usage;
use Rings::Common;

my $opt_all;
my $opt_debug;
my $opt_dumpmeta;
my $opt_help;
my $opt_manual;
my $opt_verbose;

my %DIR_LIST = ();

##############################################################################
# Subroutines
##############################################################################

# ------------------------------------------------------------------------
# Set debugging and progress switches

sub set_display {
    if ($opt_debug) {
        $CONF->debug(1);
    }
    if ($opt_dumpmeta) {
        $CONF->dumpmeta(1);
    }
    if ($opt_verbose) {
        $CONF->verbose(1);
    }
}

#------------------------------------------------------------------------
# Find matching directories

sub do_find {
    my $this_file = $_;
    my $this_path = $File::Find::name;
    if (-d $this_path) {
        my $this_dir = $File::Find::dir;
        my $prefix   = $CONF->picture_input_root;
        my $pic_dir  = $this_path;
        $pic_dir =~ s/^$prefix\///xms;
        my $found = check_dir_upload($pic_dir);
        if ($opt_all) {
            if ($found) {
                $DIR_LIST{$pic_dir} = 2;
            } else {
                $DIR_LIST{$pic_dir} = 1;
            }
            return;
        }
        if (scalar(@ARGV) > 0) {
            for my $frag (@ARGV) {
                if ($this_file =~ /$frag/xms) {
                    if ($found) {
                        $DIR_LIST{$pic_dir} = 2;
                    } else {
                        $DIR_LIST{$pic_dir} = 1;
                    }
                    return;
                }
            }
        } else {
            if ($found == 0) {
                $DIR_LIST{$pic_dir} = 1;
                return;
            }
        }
    }
    return;
}

##############################################################################
# Main Routine
##############################################################################

# -- get options
GetOptions(
    'all'      => \$opt_all,
    'debug'    => \$opt_debug,
    'dumpmeta' => \$opt_dumpmeta,
    'help'     => \$opt_help,
    'manual'   => \$opt_manual,
    'verbose'  => \$opt_verbose
);

if ($opt_debug) {
    print("DEBUG: Debugging started.");
}

# help the poor souls out
if ($opt_manual) {
    pod2usage(-verbose => 2);
}
if (scalar(@ARGV) == 0 || $ARGV[0] eq 'help') {
    $opt_help = 1;
}
if ($opt_help) {
    pod2usage(-verbose => 0);
}

my $action = shift;
my $id     = shift;

if ($opt_debug) {
    print("action = $action\n");
    print("id = $id\n");
}

my %id_list = get_id_list();
if (!$id_list{$id}) {
    print("ERROR: unknown ID $id\n");
    print("INFO: Valid IDs:\n");
    for my $i (sort keys %id_list) {
        print("    $i\n");
    }
    exit 1;
}
my $ring_conf = "/etc/rings/${id}.conf";
if ($opt_debug) {
    print("ring_conf = $ring_conf\n");
}
get_config($ring_conf);
set_display();

# -- Open up connections to the MySQL data
db_connect();

# If just looking for a directory, print the list and bail out
if ($action =~ /^f/xms) {
    if ($CONF->debug) {
        dbg('picture_input_root = ' . $CONF->picture_input_root . "\n");
    }
    find(\&do_find, $CONF->picture_input_root);
    my $footnote = '';
    for my $d (sort keys %DIR_LIST) {
        my $found = '';
        if ($DIR_LIST{$d} == 2) {
            $found    = " *";
            $footnote = "\n* directory already uploaded\n";
        }
        print("$d$found\n");
    }
    print($footnote);
    exit;
}

if ($opt_debug) {
    $CONF->debug($opt_debug);
}
if ($CONF->debug) {
    dbg("Initialize timer.");
}

my $in_dir;
if (@ARGV) {
    $in_dir = join(' ', @ARGV);
} else {
    print "ERROR: provide at least one directory to scan\n"
      or die "ERROR: problem writing to STDOUT\n";
    pod2usage(-verbose => 0);
}

my $this_dir = $CONF->picture_input_root . "/$in_dir";
if (-d $this_dir) {
    print "Adding $this_dir to processing queue ...\n";
    queue_upload($this_dir);
} else {
    print "$this_dir not a directory ... skipping\n"
      or die "ERROR: problem writing to STDOUT\n";
}

db_disconnect();

exit;

__END__

=head1 NAME

ring-load - add an input directory to the picture upload queue

=head1 SYNOPSIS

ring-load [load|find] <id> <directory1> [--conf=<configuration>]
 [--all] [--debug] [--help] [--manual]

=head1 DESCRIPTION

Add an input directory to the picture_upload_queue or list input
directories.  Directories added to the upload queue are subsequently
processed by picture-load-daemon and picture-daemon.  The processing
sequence is:

=over 4

=item 1. picture-load

This script adds input directory to the picture_load_queue table.
No further processing is performed.

=item 2. picture-load-daemon

This picture-load-daemon script performs the following actions.

=over 6

=item * Reads input directories to process from the picture_load_queue.

=item * Reads the metadata for images in the input directories.

=item * Creates an output directory using the input directory name.

=item * Moves the raw image into the raw directory and stores the
metadata in the pictures_information table.

=item * Adds a "SIZE" entry in the picture_action_queue.
 
=item * Removes the input directory from the picture_load_queue
directory.

=back

=item 3. picture-daemon

The picture-daemon script processes images in the
picture_action_queue.

=back

=head1 OPTIONS AND ARGUMENTS

=over 4

=item --all

Display all input directories including those that have already been
uploaded  The find default is to suppress directorys that have
already been processed.

=item --help

Displays help text.

=item --manual

Displays more complete help text.

=item --debug

Turns on debugging displays.

=back

=head1 SEE ALSO

ring-load-daemon, ring-daemon

=head1 AUTHOR

Bill MacAllister <bill@ca-zephyr.org>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2016-2026, Bill MacAllister <bill@ca-zephyr.org>.

This code is free software; you can redistribute it and/or modify it
under the same terms as Perl. For more details, see the full
text of the at https://opensource.org/licenses/Artistic-2.0.

This program is distributed in the hope that it will be
useful, but without any warranty; without even the implied
warranty of merchantability or fitness for a particular purpose.

=cut
