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

# This package provides:
# - A static interface for commands to log their state.
# - An XMLObject representation of the command log, that can be
#   instantiated with various filters.
#

use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::Assert;
use RSApache::Command;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::CommandLog;
use Common::FormObject;
use base 'Common::FormObject';

# This 'static' class method is used by Command objects to log their state.
#
sub Log {
    my ( $commandObj, $id ) = @_;
    assert($commandObj);

    my %logArgs;
    $logArgs{command_name} = ref($commandObj);
    if ($id) {
        $logArgs{command_id} = $id;
    }
    $logArgs{command} = $commandObj->getParamsAsString();

    my $logObj = RPS::DB::Item::CommandLog->Create(%logArgs);
    $logObj->save();
}

# jpk - It may prove handy to subclass RPS::CommandLog in the future to encapsulate
# the various arguments.
#
#
# Interface:
# (These are all optional)
#
#   user_id => <user_id>        - only show commands belonging to this user
#   command => <command_name>   - filter by command name (i.e. 'RPS::Catalog::Command::Edit');
#   most_recent => 1            - pass a true value if you want to show each 'unique' command
#                                 only once, sorted by most recent to least recent access
#   limit => <limit>            - limit the results to <limit> items.
#
sub _init {
    my ( $self, %args ) = @_;

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

    # ... going to trust the args.

    $args{limit} = 10 unless defined $args{limit};

    $self->{Item} = [];
    my $collection = RPS::DB::Item::CommandLog->Get(%args);

    while ( my $dbItem = $collection->next() ) {

        # jpk - occasionally, the log may contain references to objects
        # that no longer exist.
        # This will result in an exception getting thrown.
        # I am going to catch that exception here, and remove the log
        # entry in those cases.
        #
        my $logItem;
        eval { $logItem = $self->_createLogItemFromDBItem($dbItem); };
        if ($@) {
            if ($dbItem) {
                $dbItem->delete();
                next;
            }
        }
        push @{ $self->{Item} }, $logItem;
    }

    return $self;
}

sub _createLogItemFromDBItem {
    my ( $self, $dbItem ) = @_;
    my $logItem = RPS::CommandLog::Item->new( _dbItem => $dbItem );

    return $logItem;
}

#
# ---------------------------------
#

package RPS::CommandLog::Item;

use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::Assert;
use RSApache::Command;

use lib '/app/tools/rps/lib';
use RPS::DB::Item::CommandLog;
use Common::FormObject;
use base 'Common::FormObject';

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

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

    my %properties;
    if ( $args{_dbItem} ) {
        $self->_propertiesFromDBItem( \%properties, $args{_dbItem} );
    } elsif ( $args{commandLogID} ) {
        $self->_propertiesFromDB( \%properties, $args{commandLogID} );
    } else {
        $self->_propertiesFromDefaults( \%properties );
    }

    my $rval = $self->_initProperties( \%properties );

    return $rval;
}

sub _propertiesFromDB {
    my ( $self, $hrProperties, $id ) = @_;

    my $dbItem = RPS::DB::Item::CommandLog->Lookup( command_log_id => $id );
    $self->_propertiesFromDBItem( $hrProperties, $dbItem );
}

sub _propertiesFromDBItem {
    my ( $self, $hrProperties, $dbItem ) = @_;

    $hrProperties->{command_log_id} = $dbItem->command_log_id;
    $hrProperties->{command_name}   = $dbItem->command_name;
    $hrProperties->{command_id}     = $dbItem->command_id;
    $hrProperties->{command}        = $dbItem->command;
    $hrProperties->{date_created}   = $dbItem->date_created;
    $hrProperties->{created_by}     = $dbItem->created_by;
}

sub _propertiesFromDefaults {
    my ( $self, $hrProperties ) = @_;

}

sub _initProperties {
    my ( $self, $props ) = @_;

    $self->{CommandLogID} = Common::FormObject::Scalar::Integer->new( value => $props->{command_log_id}, readOnly => 1 );
    $self->{CommandName} = Common::FormObject::Scalar::String->new( value => $props->{command_name}, readOnly => 1 );
    $self->{CommandID} = Common::FormObject::Scalar::Integer->new( value => $props->{command_id}, readOnly => 1 );
    $self->{Command} = Common::FormObject::Scalar::String->new( value => $props->{command}, readOnly => 1 );

    $self->{CreatedDate} = Common::FormObject::Scalar::DateTime->new( value => $props->{date_created}, readOnly => 1 );
    $self->{CreatedBy}   = Common::FormObject::Scalar::UserName->new( value => $props->{created_by},   readOnly => 1 );

    return $self;
}

###
1;    # Play nicely.
###
