use strict;

use Getopt::Std;

use lib '/app/tools/common/lib';
use Common::RSDB;
use Common::DB::Item::TableChangeLog;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::Artist;
use RPS::DB::Item::Album;
use RPS::DB::Item::Song;
use RPS::DB::Item::Master;
use RPS::DB::Item::Track;
use RPS::DB::Item::Composer;
use RPS::DB::Item::Product;
use RPS::DB::Item::Label;
use RPS::DB::Item::ProductTrack;

use lib '/app/tools/mediaserve/lib';

use MediaServe::DB::Item::AlbumFile;
use MediaServe::DB::Item::ProductTrackFile;

my $gClientID;
my $gVerbosityLevel = 1;

_parseCommandLine();

print "start: " . localtime() . "\n";
_syncMetadata($gClientID);
print "end  : " . localtime() . "\n";

sub _syncMetadata {
    my ($clientID) = @_;

    my $app = Common::RSApp->new( clientID => $clientID );

    # !!! So... what is the best way to do this?
    # I would like to try and let the change log process handle most of
    # the work.  But that means that I need to 'forge' a bunch of inserts.
    #
    #+--------------------+
    #| table_name         |
    #+--------------------+
    #| artist             |
    #| album              |
    #| song               |
    #| master             |
    #| track              |
    #| composer           |
    #| product            |
    #| label              |
    #| album_file         |
    #| product_track_file |
    #| product_track      |
    #+--------------------+

    # Shouldn't be too terribly difficult - need to do it in the correct order.
    #
    # composer
    # artist
    # label
    # song
    # master   (song_id, artist_id)
    # album      (artist_id, label_id)
    # track  (album_id, master_id)
    # product (album_id,track_id)
    # product_track  (product_id, track_id)
    # album_file  (album_id)
    # product_track_file (product_track_id)

    foreach my $dbPkg (
        'RPS::DB::Item::Artist',       'RPS::DB::Item::Album',
        'RPS::DB::Item::Song',         'RPS::DB::Item::Master',
        'RPS::DB::Item::Track',        'RPS::DB::Item::Composer',
        'RPS::DB::Item::Product',      'RPS::DB::Item::Label',
        'RPS::DB::Item::ProductTrack', 'MediaServe::DB::Item::AlbumFile',
        'MediaServe::DB::Item::ProductTrackFile'
      ) {
        _syncTable($dbPkg);
    }
}

sub _syncTable {
    my ($pkg) = @_;

    my $collection = $pkg->GetAll();
    while ( my $dbItem = $collection->next() ) {
        _createInsertLog($dbItem);
    }
}

sub _createInsertLog {
    my ($dbItem) = @_;

    my $dbo = Common::RSApp->GetClientDB();
    my @setPairs;

    # !!! This violates encapsulation...
    #
    my $config    = $dbItem->_config();
    my $tableName = $dbItem->_tableName();

    foreach my $fieldName ( keys %$config ) {
        my $value = $dbItem->$fieldName;
        if ( defined $value ) {
            push @setPairs, "$fieldName=" . $dbo->DBQuote($value);
        }
    }

    my $setString = join( ",", @setPairs );
    my $logEntry = Common::DB::Item::TableChangeLog->Create(
        client_id  => Common::RSApp::GetClientID(),
        table_name => $tableName,
        action     => Common::DB::Item::TableChangeLog::kActionInsert,
        set_pairs  => $setString,
    );
    $logEntry->save();

}

sub _parseCommandLine {
    my %opt;
    getopts( 'c:V:', \%opt );

    if ( !$opt{c} ) {
        _usage();
        exit(1);
    }
    $gClientID = $opt{c};

    if ( defined $opt{V} ) {
        $gVerbosityLevel = $opt{V};
    }
}

