#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package Distribution::MetadataUpdate;

use strict;
use warnings;

use Text::ParseWords;

use lib '/app/tools/distribution/lib';
use Distribution::DB::Item::ProductDistribution;

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

use base 'Common::FormObject';

sub _init {
    my ( $self, %args ) = @_;

    $self->SUPER::_init(%args);

    $self->{_client_id} = $args{client_id};

    return $self;
}

sub getUpdateReport {
    my $self = shift;

    assert($self);
    assert( $self->{_client_id} );

    $self->{_report} = undef;

    my $updates = Common::DB::Item::TableChangeLog->GetAllUnNotified( $self->{_client_id} );

    while ( $updates->hasNext ) {
        my $update = $updates->next;

        $self->_reportUpdates($update);
    }

    return $self->{_report};
}

sub _reportUpdates {
    my $self   = shift;
    my $update = shift;
    my $dbo    = Common::RSApp::GetClientDB();

    assert($self);
    assert($update);

    my @args = $self->_setSearchCriteria($update);

    unless (@args) {
        print STDERR "Failed to parse table update args\n";
        return;
    }

    Common::Log::Debug( "ClientID: " . Common::RSApp::GetClientID() );
    my $albums = RPS::DB::Item::Album->GetAllWithChangedMetadata(@args);
    my $result;

    while ( $albums->hasNext ) {
        my $album = $albums->next;

        $self->{_report} = {} unless ( $self->{_report} );
        $self->{_report}->{ $album->album_id }->{ $update->action } = () unless ( $self->{_report}->{ $update->action } );

        $result = { table => $update->table_name, data => $dbo->DBUnQuote( $update->set_pairs ) };
        push( @{ $self->{_report}->{ $album->album_id }->{ $update->action } }, $result );

        $update->notified(1);
        $update->save();
    }

}

sub _setSearchCriteria {
    my $self   = shift;
    my $update = shift;

    assert($self);
    assert($update);

    if ( $update->action eq 'UPDATE' ) {
        return $self->_setSearchCriteriaUpdate($update);

    } elsif ( $update->action eq 'DELETE' ) {
        return $self->_setSearchCriteriaDelete($update);

    } elsif ( $update->action eq 'INSERT' ) {
        return $self->_setSearchCriteriaInsert($update);
    } else {
        die "Unknown log entry type";
    }
}

sub _setSearchCriteriaUpdate {
    my $self   = shift;
    my $update = shift;

    assert($self);
    assert($update);

    my $id_col = $update->table_name . "_id";

    my %where = _parsePairString( $update->where_pairs );

    return () unless ( $where{$id_col} );

    my $dbo = Common::RSApp::GetClientDB();

    # TODO: Find a better way to unquote/unescape a string;
    $where{$id_col} = $dbo->DBUnQuote( $where{$id_col} );
    return ( $id_col, $where{$id_col}, $update->date_created );
}

sub _setSearchCriteriaDelete {
    my $self   = shift;
    my $update = shift;

    assert($self);
    assert($update);

    my $id_col = $update->table_name . "_id";

    my %where = _parsePairString( $update->where_pairs );

    return () unless ( $where{$id_col} );

    return ( $id_col, $where{$id_col}, $update->date_created );
}

sub _setSearchCriteriaInsert {
    my $self   = shift;
    my $update = shift;

    assert($self);
    assert($update);

    my $id_col = $update->table_name . "_id";

    my %set = _parsePairString( $update->set_pairs );

    return () unless ( $set{$id_col} );

    return ( $id_col, $set{$id_col}, $update->date_created );
}

sub _parsePairString {
    my ($string) = @_;

    my %resultHash;
    my @pairs = Text::ParseWords::quotewords( ',', 0, $string );

    foreach my $pair (@pairs) {
        my ( $key, $value ) = Text::ParseWords::quotewords( '=', 0, $pair );
        $resultHash{$key} = $value;
    }

    return %resultHash;
}

1;
