#!/usr/bin/perl

use DBI;
use DBD::mysql;
use Config::INI::Reader;

sub ltrim { my $s = shift; $s =~ s/^\s+//;       return $s };
sub rtrim { my $s = shift; $s =~ s/\s+$//;       return $s };
sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };

my $confcontents = Config::INI::Reader->read_file('/etc/homeaudio.ini');
my $Config = $confcontents->{_};

$dsn = "DBI:mysql:" . $Config->{DBNAME} . ":" . $Config->{DBHOST};
$dbh = DBI->connect($dsn, $Config->{DBUSER}, $Config->{DBPASS}, {RaiseError=>1});

$mp3dir = $Config->{MP3DIR};

# Check for the existence of SAFETYFILES from the config file before proceeding
my @safetyfiles = split(/,/, trim($Config->{SAFETYFILES}));
for ( my $i=0; $i<@safetyfiles; $i++ ) {
   if ( ! -e $Config->{MP3DIR} . $safetyfiles[$i] ) {
      print "Missing safety file \"$safetyfiles[$i]\"! Exiting...\n";
      exit(1);
   }
}

# Get the current default list (if there is one);
$activelist = "";
$sth = $dbh->prepare("SELECT id FROM queues WHERE active='true'");
$sth->execute();
if ( $sth->rows > 0 ) {
   @result = $sth->fetchrow_array();
}
$activelist = $result[0];
$sth->finish();

# Create the year queues from the list in the config file if they don't already exist
# Must be at least one year!!!
@years = split(/,/, trim($Config->{YEARDECADES}));
for ( my $i=0; $i<@years; $i++ ) {
   $years[$i] = trim($years[$i]);
   $sth = $dbh->prepare("INSERT IGNORE INTO queues (name, type) VALUES(?, 'year')");
   $queuename = $years[$i] . "'s";
   $sth->execute($queuename);
   $sth->finish();
}

# Populate and prune the "year" queues (i.e. 1990's)
# First we get all the "year" queues
my %yearqueues; # This will be populated from the database
$sth = $dbh->prepare("SELECT id, name FROM queues WHERE type='year'");
$sth->execute();
while ( @row = $sth->fetchrow_array ) {
   $yearqueues{$row[0]} = substr($row[1], 0, 4);
}
$sth->finish();
# First we remove any songs which don't have the correct year
while ( ($yqid, $year) = each %yearqueues ) {
   $yearend = $year + 10;
   $sth = $dbh->prepare("DELETE FROM queuecontents WHERE qid=$yqid AND songid NOT IN (SELECT id FROM songs WHERE year >= $year AND year < $yearend)");
   $sth->execute();
}
$sth->finish();

# Push any song genres which don't already exist into queues.
$sth = $dbh->prepare("INSERT INTO queues (name, type) SELECT DISTINCT(genre) AS genre, 'auto' FROM songs WHERE genre NOT IN (SELECT name FROM queues) AND genre NOT IN (SELECT genre FROM excludes)");
$sth->execute();
$sth->finish();

# Remove any auto queues which don't have corresponding genres in songs.
$sth = $dbh->prepare("DELETE FROM queues WHERE name NOT IN (SELECT DISTINCT(genre) FROM songs) AND type='auto'");
$sth->execute();
$sth->finish();

# Now we insert all the songs for each year into the appropriate queue, ignoring duplicates
# We want to restrict it to a subset of the queues so we'll make an array of queue IDs for the ones we want.
# The config parameter QUEUESINYEARS must have a comma separated list of queue names to include in the years. Must be at least 1!!
# First we get the queue names from the config into a database query friendly string for use with "IN"
my @dbqueuenames = split(/,/, trim($Config->{QUEUESINYEARS}));
my $wantedqueuenames = "";
for ( my $i=0; $i<@dbqueuenames; $i++ ) {
   $wantedqueuenames .= "\"" . trim($dbqueuenames[$i]) . "\",";
}
$wantedqueuenames = substr($wantedqueuenames, 0, -1);
# Then we get the list of IDs based on that friendly string and build a new friendly string for the queue IDs
$sth = $dbh->prepare("SELECT id FROM queues WHERE name IN ($wantedqueuenames)");
$sth->execute();
my $wantedqueuesquery = "";
while ( @row = $sth->fetchrow_array ) {
   $wantedqueuesquery .= $row[0] . ",";
}
$sth->finish();
$wantedqueuesquery = substr($wantedqueuesquery, 0, -1);
while ( ($yqid, $year) = each %yearqueues ) {
   $yearend = $year + 10;
   $sth = $dbh->prepare("INSERT IGNORE INTO queuecontents (qid, songid) SELECT $yqid, s.id FROM queuecontents AS qc LEFT JOIN songs AS s on qc.songid=s.id WHERE qc.qid IN ($wantedqueuesquery) AND year >= $year AND year < $yearend");
   $sth->execute();
}
$sth->finish();

# Add any missing songs from distinct genres into the appropriate queue.
$sth = $dbh->prepare("INSERT IGNORE INTO queuecontents (qid, songid, timesplayed) SELECT q.id, s.id, 0 FROM songs AS s LEFT JOIN queues AS q ON s.genre=q.name WHERE q.id IS NOT NULL");
$sth->execute();
$sth->finish();

# Remove any queue contents for which the song is missing.
$sth = $dbh->prepare("DELETE FROM queuecontents WHERE songid NOT IN (SELECT id FROM songs)");
$sth->execute();
$sth->finish();

# Since it is possible for the active queue to have been removed (unlikely)
# the lowest indexed queue ID will be made active if no queue is active.
$sth = $dbh->prepare("SELECT id FROM queues WHERE active='true'");
$sth->execute();
if ( $sth->rows == 0 ) {
   $sth = $dbh->prepare("SELECT MIN(id) FROM queues");
   $sth->execute();
   @result = $sth->fetchrow_array();
   $sth = $dbh->prepare("UPDATE queues SET active='true' WHERE id=?");
   $sth->execute($result[0]);
}

# Close the DB connection
$sth->finish();
$dbh->disconnect();
