#------------------------------------------------------------
# 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;
