#------------------------------------------------------------
# Copyright (C) 2007 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
#
#------------------------------------------------------------
# Validation Album Sequential Object.  Extends the Validate
# Rule class.  This object contains the method to do
# validation on piece of data.
#
# Test the target field to ensure all rows contain sequential
# data with no duplicates.
#
#
# Base Class:
#   Validation::Rule
#
# Public methods:
#   + Metadata::Rule::Album::Sequential new();
#   + $fail_status         ok();
#   + $scalar              AUTOLOAD( $scalar );
#------------------------------------------------------------
package Metadata::Rule::Album;
use strict;

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

use lib '/app/tools/metadata/lib';
use base 'Validate';
use base 'Validate::Rule';

use Metadata::DB::Item::ContentImportData;

use vars qw($AUTOLOAD);

###
# Define addition public accessors
###
use constant kClassAttributes => qw( target_field unifying_field );

#------------------------------------------------------------
# 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.
#
# This method is almost identical base class AUTOLOAD method
# except the method calls the parent AUTOLOAD instead of
# dying when an unknown attribute was seen.
#
# 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 and all-cap methods

    unless ( $self->{_attributes}->{$field} ) {
        my $superior = "SUPER::$field";
        $self->$superior(@_);
    }

    # All preconditions are validated.  Let's do some work.
    if ( defined($value) ) {
        assert( $self->_is_valid_column($value), "Invalid column name: $value" )
          if ( $field =~ /^target_field|unifying_field$/ );

        $self->{$attr} = $value;
    }

    return $self->{$attr};
}

#------------------------------------------------------------
# bool is_configured()
# Determine if this Rule object has been properly configured.
# If the unifying_filed and target_field 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->{_unifying_field} && $self->{_target_field} );
}

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

#------------------------------------------------------------
# Validate::Rule _init()
# Initialize the object.
#
# - Build accessor method hash
# - set internal private data ( message, fail_status, and
#   parameter ). See the base class for parameter defintions.
#------------------------------------------------------------
sub _init {
    my ( $self, %args ) = @_;
    my @paramlist;

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

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

    $self->fail_status( defined( $args{fail_status} ) ? $args{fail_status} : Validate::kStatusDefault );

    return $self;
}

sub _is_valid_column {
    my ( $self, $column ) = @_;
    assert( defined($column), "column required" );

    my $dbItem  = Metadata::DB::Item::ContentImportData->Create();
    my @columns = $dbItem->GetColumns();
    my @found   = grep( /^$column$/, @columns );

    return grep( /^$column$/, @columns ) ? 1 : undef;
}

1;
