#------------------------------------------------------------
# Copyright (C) 2007 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------

#------------------------------------------------------------
# Validation Rule Object.  Base class that defines rules
# that should be applied to Validate Items.  A rule is a test
# that should be performed on a piece of data.  Each child
# class that inherits from Validate::Rule needs to define an
# ok method.  The ok method is the method that actually does
# the data validation.
#
# Public methods:
#   + Validate::Rule     new();
#   + bool               is_configured();
#   + $scalar            AUTOLOAD( $scalar );
#
# Public data:
#   message    - Message to send when rule fails.  Overrides
#                the default message. ** optional **
#   parameter  - Test parameters to psss to the rule.  The
#                data type is completly rule specific.
#------------------------------------------------------------

package Validate::Rule;
use strict;

use lib '/app/tools/common/lib';
use Common::Log;
use Common::RSApp;
use Common::Assert;

use Validate;

use vars qw( $AUTOLOAD );

###
# Define what public data members belong to this object.
###
use constant kClassAttributes => qw( message parameter fail_status );

#------------------------------------------------------------
# Public Methods
#------------------------------------------------------------

#------------------------------------------------------------
# Constructor
#------------------------------------------------------------
sub new {
    my ( $class, %args ) = @_;
    my $self = bless {}, $class;

    return $self->_init(%args);
}

#------------------------------------------------------------
# $scalar AUTOLOAD( $scalar )
#
# Accessor methods for this object.  Methods to access the
# private data in this object.  Valid members are defined in
# the kClassAttributes constant.
#
# If a scalar is passed in this method will set the
# corrisponding private data member.
#
# This method always returns the value of the corrisponding
# private data member.
#
# Parameters:
#   $scalar - Set the private data member to this value.
#             ** optional **
#
# Return:
#   $scalar - private memeber value
#------------------------------------------------------------
sub AUTOLOAD {
    my $self  = shift;
    my $value = shift;
    my $field = $AUTOLOAD;
    $field =~ s/.*://;    # Strips fully-qualified portion.

    my $attr = "_$field";

    return if $field eq 'DESTROY';    # skip DESTROY method

    # ensure this is a valid attribute name
    die("Invalid attribute ($field), see kClassAttributes")
      unless ( $self->{_attributes}->{$field} );

    ###
    # All preconditions are validated.  Let's do some work.
    ###

    # If a value is sent in, then set it.
    $self->{$attr} = $value
      if ($value);

    return $self->{$attr};
}

#------------------------------------------------------------
# bool is_configured()
# Determine if this Rule object has been properly configured.
# If the parameter data member has been defined then we
# assume that all is good.
#
# Return:
#   bool - has this object been configured.
#------------------------------------------------------------
sub is_configured {
    my ($self) = @_;
    assert($self);

    return defined( $self->{_parameter} );
}

#------------------------------------------------------------
# Private Methods
#------------------------------------------------------------

#------------------------------------------------------------
# Validate::Rule _init()
# Initialize the object.  All this initializer does is create
# a hash of valid public attributes.
#------------------------------------------------------------
sub _init {
    my ( $self, %args ) = @_;

    # Build a hash with our valid class attributes
    foreach ( (kClassAttributes) ) {
        $self->{_attributes}->{$_}++;
    }

    return $self;
}

1;
