#------------------------------------------------------------
# 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::Unique;
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 'Metadata::Rule::Album';

use vars qw($AUTOLOAD);

###
# Default failure message if the OK method fails.
###
use constant kFailureMessage => "must be unique";

use constant kClassAttributes => qw( allow_duplicates per_album );

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

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

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

#------------------------------------------------------------
# $fail_status ok( $target_data )
#
# Check for multually exclusive fields.
#
# Parameters:
#   $target_data - Data we will be testing.
#
# Return:
#   $fail_status - kStatusOK (0) if the test passes, any
#                  non-zero should be considered a failure.
#------------------------------------------------------------
sub ok {
    my ( $self, $target, %args ) = @_;
    my $success = Validate::kStatusOK;
    my $fail =
      defined( $self->{_fail_status} )
      ? $self->{_fail_status}
      : Validate::kStatusDefault;

    return $success unless ( $self->target_field() );
    my $field = $self->target_field();

    my $oImport = Metadata::DB::Item::ContentImportData->Lookup( content_import_data_id => $args{id} );
    return $success unless ($oImport);

    my $target_data = $oImport->$field();
    return $success unless ( defined($target_data) && length($target_data) );

    my $limit_to_album_sql = "catalog_no = '$target'"
      if ( $self->per_album() );

    my $dbo = Common::RSApp::GetClientDB();
    my $target_select =
      $self->allow_duplicates()
      ? "DISTINCT(" . $self->target_field() . ")"
      : $self->target_field;

    return undef unless ( $self->is_configured() );

    return $success unless ( defined($target) );

    my $has_dups = Metadata::DB::Item::ContentImportData::HasImportDuplicates(
        target         => $target_data,
        fields         => $field,
        other_criteria => $limit_to_album_sql
    );

    return $has_dups ? $fail : $success;
}

#------------------------------------------------------------
# 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 ) = @_;

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

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

    $self->message( $args{message} ? $args{message} : kFailureMessage );

    return $self;
}
1;
