#!/usr/bin/perl

use strict;
use Cwd;
use DBI;
use Getopt::Long;
use Image::ExifTool 'ImageInfo';
use Image::Magick;
use Pod::Usage;
use Rings::Common;

my $cnt;
my $opt_conf;
my $opt_debug;
my $opt_end;
my $opt_help;
my $opt_id;
my $opt_manual;
my $opt_progress;
my $opt_signature;
my $opt_start;
my $opt_update;

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

# ------------------------------------------------
# process the files

sub read_and_update {
    my ($pid_start, $pid_end) = @_;

    my $sel = 'SELECT picture_details.pid';
    $sel .= ', picture_details.mime_type';
    $sel .= ', pictures_information.raw_signature';
    $sel .= ', pictures_information.picture_lot';
    $sel .= ', picture_types.file_type';
    $sel .= ' FROM picture_details';
    $sel .= ' JOIN pictures_information';
    $sel .= ' ON (pictures_information.pid = picture_details.pid)';
    $sel .= ' JOIN picture_types';
    $sel .= ' ON (picture_types.mime_type = picture_details.mime_type)';
    $sel .= " WHERE picture_details.size_id = 'raw'";
    $sel .= " AND picture_details.pid >= $pid_start";
    $sel .= " AND picture_details.pid <= $pid_end";

    if ($opt_debug) {
        dbg($sel);
    }

    my $sth = $DBH->prepare($sel);
    $sth->execute();
    if ($sth->err) {
        sql_die($sel, $sth->err, $sth->errstr);
    }
    my $cnt_read     = 0;
    my $cnt_update   = 0;
    my $cnt_progress = 0;
    while (my $row = $sth->fetchrow_hashref) {
        $cnt_read++;
        $cnt_progress++;
        if ($opt_progress && $cnt_progress > $opt_progress) {
            print("Records read: $cnt_read\n");
            $cnt_progress = 0;
        }
        if ($opt_signature) {
            my $pid            = $row->{pid};
            my $pic_lot        = $row->{picture_lot};
            my $raw_file_type  = $row->{file_type};
            my $raw_file       = "$pic_lot/raw/${pid}.$raw_file_type";
            my $pic_path       = $CONF->picture_root . "/$raw_file";
            my $db_signature   = $row->{raw_signature};
            my $file_signature = image_signature($pic_path);
            if ($opt_debug) {
                dbg("file: $pic_path");
                dbg("file: $file_signature");
                dbg("  db: $db_signature");
            }
            if ($row->{raw_signature} ne $file_signature) {
                my $cmd = 'UPDATE pictures_information SET';
                $cmd .= ' raw_signature=?';
                $cmd .= ' WHERE pid=? ';
                if ($opt_debug) {
                    dbg($cmd);
                    dbg("file_signature: $file_signature");
                    dbg("pid: $pid");
                }

                if ($opt_update) {
                    $cnt_update++;
                    print "Updating signature for $pid\n";
                    my $sth_update = $DBH_UPDATE->prepare($cmd);
                    if ($sth_update->err) {
                        sql_die($cmd, $sth_update->err, $sth_update->errstr);
                    }
                    $sth_update->execute($file_signature, $pid);
                    if ($sth_update->err) {
                        sql_die($cmd, $sth_update->err, $sth_update->errstr);
                    }
                } else {
                    print 'Proposing signature for ' . $row->{pid};
                    print ' of ' . $file_signature . "\n";
                }
            }
        }
    }

    print("   Records read: $cnt_read\n");
    print("Records updated: $cnt_update\n");
    return;
}

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

print ">>> ring-set-info\n";

# -- get options
GetOptions(
    'debug'      => \$opt_debug,
    'conf=s'     => \$opt_conf,
    'end=i'      => \$opt_end,
    'help'       => \$opt_help,
    'id=s'       => \$opt_id,
    'manual'     => \$opt_manual,
    'progress=i' => \$opt_progress,
    'signature'  => \$opt_signature,
    'start=i'    => \$opt_start,
    'update'     => \$opt_update
);

# help the poor souls out
if ($opt_help) {
    pod2usage(-verbose => 0);
}
if ($opt_manual) {
    pod2usage(-verbose => 2);
}

# Set the picture range to process from the command line
my $pid_start = $opt_start;
if ($pid_start < 1) {
    print("ERROR --start must be greater than one\n");
    pod2usage(-verbose => 0);
}
my $pid_end = $opt_start;
if ($opt_end > $pid_end) {
    $pid_end = $opt_end;
}

my %id_list = get_id_list();
if (!$id_list{$opt_id}) {
    print("ERROR: unknown ID $opt_id\n");
    print("INFO: Valid IDs:\n");
    for my $i (sort keys %id_list) {
        print("    $i\n");
    }
    exit 1;
}

my $ring_conf = "/etc/rings/${opt_id}.conf";
get_config($ring_conf);
if ($opt_debug) {
    $CONF->debug(1);
}
if ($CONF->debug) {
    dbg("ring_conf = $ring_conf\n");
}
db_connect();

read_and_update($pid_start, $pid_end);

exit;

__END__

=head1 NAME

ring-set-info - set picture information from the raw picture

=head1 SYNOPSIS

ring-set-info --start=<int> --id=<ring id> [--end=<int>] [--update]
[--progress=int] [--signature] [--debug] [--help] [--manual]


=head1 DESCRIPTION

Set information from the raw picture.

=head1 OPTIONS AND ARGUMENTS

=over 4

=item --id=<ring id>

The ring id to process.  Required.

=item --start=int

The picture id to start processing pictures_information entries.
Required.

=item --end=int

The picture id to end processing pictures_informatation entries.
If not specified then set the ending picture id to the starting
picture id.

=item --progress=<int>

Display progress every <int> entries processed.

=item --signature

Update raw_signatures in the database that do not match the values
derived from the files.

=item --update

Actually load the data into the rings database.

=item --help

Displays help text.

=item --manual

Displays more complete help text.

=item --debug

Turns on debugging displays.

=back

=head1 AUTHOR

Bill MacAllister <bill@macallister.grass-valley.ca.us>

=cut
