#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package RPS::Catalog::ErrorReport;
use strict;
use warnings;

use Data::Dumper;

use lib '/app/tools/rps/lib';
use RPS::Catalog::AlbumError;
use RPS::Track::TrackList;
use RPS::Product::Product;
use RPS::DB::Item::Product;

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

use base 'Common::FormObject';

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

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

    $self->_propertiesFromValidation(%args);

    return $self;
}

sub _propertiesFromValidation
{
    my $self = shift;
    my %args = @_;
    assert($self);

    $self->{Album}             = new RPS::Catalog::AlbumError( albumID => $args{albumID} );
    $self->{AlbumErrors}       = $self->_validateAlbumData( %args );
    $self->{ProductErrors}     = $self->_validateProduct( %args );
    $self->{Assets}            = $self->_validateAssets( %args );

    ( $self->{SingleTrackErrors}, $self->{MultiTrackErrors} ) = $self->_validateTrack( %args );
}

sub _validateAlbumData
{
    my $self = shift;
    my %args = @_;
	my $errors = {};

    my $harness = new Metadata::Validate::Harness( failState => Validate::kStatusOK, ignoreCurrentData => 1 );
    my $album   = new RPS::Catalog::AlbumError( albumID => $args{albumID} );
    $album->_validateMetadata( metadataValidator => $harness );

	foreach ( keys %$album ) {
		next unless( /^[A-Z]/ && ref($album->{$_}) );

        my $albumErrors = $album->{$_};
		$errors->{$_} = $album->{$_}->{_xmlParams}->{emsg} if( $album->{$_}->{_xmlParams}->{emsg} );
	}

    return $errors;
}

sub _validateTrack
{
    my $self = shift;
    my %args = @_;

    my $multiErrors = {};
    my $singleErrors = {};
	my $trackErrors = {};
	my $err;
	my $s_err;

    my $harness = new Metadata::Validate::Harness( failState => Validate::kStatusOK, ignoreCurrentData => 1 );
    my $oTracks = new RPS::Track::TrackList( %args );
	my $tracks = $oTracks->getTracks();
    my $track;

    my @singleTracksWithErrors;

    foreach $track ( @$tracks ) {
		$track->_validateMetadata( metadataValidator => $harness );

	    ###
        #   Multi-track edit errors
        ###
        if( $track->{Master} && $track->{Master}->{ISRC} ) {
            $err = $track->{Master}->{ISRC}->{_xmlParams}->{emsg};

            unless( $err ) {
                $err = "Duplicate detected" if( $track->{Master}->{ISRC}->{_xmlParams}->{e} );
            }

			$multiErrors->{ISRC}->{$err} = 1 if( $err );
		}

		if( $track->{Title} ) {
            $err = $track->{Title}->{_xmlParams}->{emsg};
			$multiErrors->{Title}->{$err} = 1 if( $err );
		}

		if( $track->{ParentalAdvisory} ) {
            $err = $track->{ParentalAdvisory}->{_xmlParams}->{emsg};
			$multiErrors->{ParentalAdvisory}->{$err} = 1 if( $err );
		}

		if( $track->{MediaType} ) {
            $err = $track->{MediaType}->{_xmlParams}->{emsg};
			$multiErrors->{MediaType}->{$err} = 1 if( $err );
		}

		if( $track->{Length} ) {
            $err = $track->{Length}->{_xmlParams}->{emsg};
			$multiErrors->{Length}->{$err} = 1 if( $err );
		}

		if( $track->{ArtistName} ) {
            $err = $track->{ArtistName}->{_xmlParams}->{emsg};
			$multiErrors->{ArtistName}->{$err} = 1 if( $err );
		}

		if( $track->{TrackOrder} ) {
            $err = $track->{TrackOrder}->{_xmlParams}->{emsg};
			$multiErrors->{TrackOrder}->{$err} = 1 if( $err );
		}


        ###
        #   Single-track edit errors
        ###
        $s_err = undef;
        my $s_err_found = undef;


        if( $track->{Master} && $track->{Master}->{Title} ) {
            $s_err = $track->{Master}->{Title}->{_xmlParams}->{emsg};
            $s_err_found = 1 if( $s_err );
			$singleErrors->{Title}->{$s_err} = 1 if( $s_err );
		}

        if( $track->{Master} && $track->{Master}->{ArtistName} ) {
            $s_err = $track->{Master}->{ArtistName}->{_xmlParams}->{emsg};
            $s_err_found = 1 if( $s_err );
			$singleErrors->{ArtistName}->{$s_err} = 1 if( $s_err );
		}

        if( $track->{Master} && $track->{Master}->{DateRecorded} ) {
            $s_err = $track->{Master}->{DateRecorded}->{_xmlParams}->{emsg};
            $s_err_found = 1 if( $s_err );
			$singleErrors->{DateRecorded}->{$s_err} = 1 if( $s_err );
		}

        my $song = $track->{Master}->{Song} if( $track->{Master} );

        if( $song ) {

            if( $song->{Title} ) {
                $s_err = $song->{Title}->{_xmlParams}->{emsg};
                $s_err_found = 1 if( $s_err );
			    $singleErrors->{SongTitle}->{$s_err} = 1 if( $s_err );
		    }

            if( $song->{ComposerName} ) {
                $s_err = $song->{ComposerName}->{_xmlParams}->{emsg};
                $s_err_found = 1 if( $s_err );
			    $singleErrors->{Composer}->{$s_err} = 1 if( $s_err );
		    }

        }


        $trackErrors->{$track->TrackOrder} = 1 if( $s_err_found );
        push( @singleTracksWithErrors, $track) if( $s_err_found );
	}

	my $multiResult;
	my $singleResult;

	foreach ( keys( %$multiErrors ) ) {
        my $msgs = join( ",", keys( %{$multiErrors->{$_}} ) );
		$multiResult->{$_} = $msgs;
	}

    foreach ( keys( %$singleErrors ) ) {
        my $msgs = join( ",", keys( %{$singleErrors->{$_}} ) );
		$singleResult->{$_} = $msgs;
    }

    if( $singleResult ) {
        my @tracks = sort { $a <=> $b } keys(%$trackErrors);
        #$singleResult->{Tracks}->{TrackOrder} = \@tracks;
        $singleResult->{Tracks}->{Track} = \@singleTracksWithErrors;
    }

	return ($singleResult, $multiResult);
}

sub _validateProduct
{
    my $self = shift;
    my %args = @_;
	my $errors = {};

    my $dbProduct = RPS::DB::Item::Product->GetDigitalAlbumProduct( $args{albumID} );
    my $harness   = new Metadata::Validate::Harness( failState => Validate::kStatusOK, ignoreCurrentData => 1 );

    my $product   = new RPS::Product::Product( _dbItem => $dbProduct );
    $product->validate( metadataValidator => $harness );

    $errors = { Product => "no digital product" } unless( $dbProduct );

	foreach ( keys %$product ) {
		next unless( /^[A-Z]/ && ref($product->{$_}) );

		$errors->{$_} = $product->{$_}->{_xmlParams}->{emsg} if( $product->{$_}->{_xmlParams}->{emsg} );

        if( $_ eq 'UPC' ) {
            $errors->{$_} = "UPC Required"
                unless( $product->UPC );

            $errors->{$_} = "Invalid UPC"
                unless( Validate::Util::is_valid_upc_or_ean( $product->UPC ) );
        }

	}

    if( $product->TrackList ) {
        foreach my $track ( @{$product->TrackList->getTracks} ) {
            foreach my $field ( qw( DiscNumber DiscTrack ) ) {
                $errors->{$field}  = $track->{$field}->{_xmlParams}->{emsg}
                    if( $track->{$field}->{_xmlParams}->{emsg} );
            }
        }
    }

    $errors->{Product} = $product if( keys(%$errors) );

    return $errors;
}

sub _validateAssets
{
    my $self = shift;
    my %args = @_;

    my $result = {};

    $result->{Image} = $self->_validateImageAssets( $args{albumID} );
    $result->{Audio} = $self->_validateAudioAssets( $args{albumID} );

    return $result;
}


sub _validateImageAssets {
    my $self = shift;
    my $album_id = shift;
    my $client_id = Common::RSApp::GetClientID();
    my $path;

    assert( $album_id, "Album ID Required" );

    my $image_assets = MediaServe::DB::Item::AlbumFile->Search( album_id => $album_id );

    return ( "missing" ) unless( $image_assets->hasNext() );

    while( $image_assets->hasNext ) {
        my $asset = $image_assets->next();
        (undef, $path) = MediaServe::Server::GetImagePath( clientID => $client_id,
                                                           mediaFileID => $asset->media_file_id );

        if( ! -f $path ) {
            Common::Log::Print( "Does not exist: $path" );
            return "processing";
        }
    }

    return undef;
}

sub _validateAudioAssets {
    my $self = shift;
    my $album_id = shift;
    my $client_id = Common::RSApp::GetClientID();
    my $path;

    assert( $album_id, "Album ID Required" );

    my $audio_assets = MediaServe::DB::Item::ProductTrackFile->Search( album_id => $album_id );
    return ( "missing" ) unless( $audio_assets->hasNext() );

    while( $audio_assets->hasNext ) {
        my $asset = $audio_assets->next();
        (undef, $path) = MediaServe::Server::GetAudioPath( clientID    => $client_id,
                                                           mediaFileID => $asset->media_file_id );
        if( ! -f $path ) {
            Common::Log::Print( "Does not exist: $path" );
            return ( "processing" );
            return undef;
        }
    }

	my $collection = RPS::DB::Item::Album->SearchNoAudio( album_id => $album_id );

    if( $collection->hasNext() ) {
        return "missing";
    }

    return MediaServe::DB::Item::ProductTrackFile::hasUnmatchedAudio( album_id => $album_id ) ? "unmatched" : undef;
}

1;
