#---------------------------------------------------------------
# ____                   _ _         ____  _
#|  _ \ ___  _   _  __ _| | |_ _   _/ ___|| |__   __ _ _ __ ___
#| |_) / _ \| | | |/ _` | | __| | | \___ \| '_ \ / _` | '__/ _ \
#|  _ < (_) | |_| | (_| | | |_| |_| |___) | | | | (_| | | |  __/
#|_| \_\___/ \__, |\__,_|_|\__|\__, |____/|_| |_|\__,_|_|  \___|
#            |___/             |___/
#
# Copyright (C) 2013 RoyaltyShare, Inc.   All Rights Reserved
#---------------------------------------------------------------

package RPS::Import::Caroline::v2;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

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

use lib '/app/tools/rps/lib';
use RPS::Import::ServiceMap;

use base 'RPS::Import::MapFaceBase';
use base 'RPS::Import::Importer';


sub _fieldMap {
    my $self = shift;
    my $version = $self->_version;

    my %field_map = (
        2 => {
            type          => 'J',  # requires _productTypes hash
            artistName    => 'E',
            upc           => 'F',
            albumName     => 'G',
            isrc          => 'H',
            trackName     => 'I',
            units         => 'L',
            price         => 'K',
        },
        6 => {
            type          => 'K',  # requires _productTypes hash
            artistName    => 'F',
            upc           => 'G',
            albumName     => 'H',
            isrc          => 'I',
            trackName     => 'J',
            units         => 'M',
            price         => 'L',
        },
        14 => {
            dateBegin     => 'B',
            type          => 'J',  # requires _productTypes hash
            artistName    => 'E',
            upc           => 'F',
            albumName     => 'G',
            isrc          => 'H',
            trackName     => 'I',
            units         => 'L',
            price         => 'K',
        },
    );
    return $field_map{$version};
}

sub _unverifiedFieldMap {
    my $self = shift;
    my $version = $self->_version;

    my %field_map = (
        2 => {
            year     => 'A',
            month    => 'B',
        },
        6 => {
            year     => 'B',
            month    => 'C',
        },
        14 => {},
    );
    return $field_map{$version};
}



sub _headerIdentifier { ( upc => qr/CPRS new UPC code|UPC/ ) }

# Note: keys must be lowercase
#
sub _productTypes {
    {
        'audio album perm. kiosk' =>
        {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },      
        'audio cloud services' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },          
        'audio cloud services - subscr' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },          
        'audio track perm. kiosk' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream portable' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'audio track stream portable - subscr' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },         
        'audio track stream webcast' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },              
        'audio track stream webcast non-royalty' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'audio track stream webcast portable' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },    
        'dig mob aud track perm download' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },            
        'dig mob aud track perm mast (real) tones' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'dig mob aud track perm callrgs/rgbacks' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_RINGTONE,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'dig mob aud track play/stream (mob ota)' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'dig mob vid single perm download' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },  
        'digital allocations streams (audio)' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },               
        'digital mob aud track perm  download' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'digital mob vid single perm download' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },              
        'digital mobile audio album permanent' =>
        {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },                          
        'digital online aud album permanent' =>
        {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'digital online aud bund stream' =>
        {
            productType => RPS::File::Sale::TYPE_ALBUM,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'digital online aud track permanent' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud track stream' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'digital online aud track stream - subscr' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'digital online vid track permanent' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_DOWNLOAD,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
        'digital online vid track stream' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },        
        'ringback - no copyright' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },        
        'user generated content stream' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeAudio,
        },
        'video cloud services' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },        
        'video stream video portable' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },        
        'video stream webcasting' =>
        {
            productType => RPS::File::Sale::TYPE_TRACK,
            formatType  => RPS::File::Sale::FORMAT_STREAM,
            mediaType   => RPS::DB::Item::MediaType::kMediaTypeVideo,
        },
    }
}

sub productType {
    my $self  = shift;
    my $trackName  = $self->_getByFieldName('trackName');
    my $isrc       = $self->_getByFieldName('isrc');

    if( $isrc eq '#' && $trackName =~ /^not assigned$/i ) # outlier
    {
        return RPS::File::Sale::TYPE_ALBUM;  # override _productTypes hash
    }
    
    my $productType = $self->SUPER::productType();

    if ($productType) {
        return $productType;
    } else {
        my $type = $self->_getByFieldName('type');
        return $self->handleError("Unable to determine product type from '$type'", RPS::DB::Item::SaleImportError::kErrorProductType);
    }
}

sub formatType {
    my $self  = shift;
    
    my $formatType = $self->SUPER::formatType();

    if ($formatType) {
        return $formatType;
    } else {
        my $type = $self->_getByFieldName('type');
        return $self->handleError("Unable to determine format type from '$type'", RPS::DB::Item::SaleImportError::kErrorFormatType);
    }
}

sub mediaType {
    my $self  = shift;
    
    my $mediaType = $self->SUPER::mediaType();

    if ($mediaType) {
        return $mediaType;
    } else {
        my $type = $self->_getByFieldName('type');
        return $self->handleError("Unable to determine media type from '$type'", RPS::DB::Item::SaleImportError::kErrorMediaType);
    }
}

sub saleDates {
    my $self  = shift;
    my $dateBegin;
    my $dateEnd;

    if( exists $self->_fieldMap->{'dateBegin'} )
    {
        my $dt = $self->_getByFieldName('dateBegin');
        return $self->_getDates( date_begin => $dt );
    }
    else
    {
        my $year  = $self->_getByFieldName('year');
        my $month = $self->_getByFieldName('month');

        my %months = (
            'JAN' => '01',
            'FEB' => '02',
            'MAR' => '03',
            'APR' => '04',
            'MAY' => '05',
            'JUN' => '06',
            'JUL' => '07',
            'AUG' => '08',
            'SEP' => '09',
            'OCT' => '10',
            'NOV' => '11',
            'DEC' => '12',
        );

        # we were originally getting 3 letter months (JAN) and the file switched to full month
        # names (January), so I added the following line to convert it
        $month = uc(substr($month, 0, 3));

        $dateBegin = sprintf("%04d-%02d-%02d", $year, $months{$month}, 1);
        $dateEnd   = sprintf("%04d-%02d-%02d", $year, $months{$month}, Days_in_Month($year, $months{uc($month)}));
    }
    return ($dateBegin, $dateEnd);

}

sub countryCode {
    my $self = shift;
    return $self->{_countryCode};
}

sub currencyCode {
    my $self = shift;
    return $self->{_currencyCode};
}

sub units {
    my $self = shift;
    my $u = $self->_getByFieldName('units') || 0;
    my $p = $self->_getByFieldName('price');

    # Follow the sign of the revenue...
    #
    if( $p > 0 )
    {
        return ( $u < 0 ) ? abs($u) : $u;
    }
    elsif( $p < 0 )
    {
        return ( $u < 0 ) ? $u : ($u * -1);
    }
    return $u;
}

sub unitPrice { abs( shift->SUPER::unitPrice ) }

sub _isValidSaleRecord {
    my $self = shift;

    my $u = $self->_getByFieldName('units') || 0;
    my $p = $self->_getByFieldName('price');
    my $type = $self->_getByFieldName('type');

    return 0 if( !$type );     # skip if summary line (no product type)

    # Skip footer section
    #
    if( exists $self->_unverifiedFieldMap->{'month'} && exists $self->_unverifiedFieldMap->{'year'} )
    {
        return 0 if( $self->_getByFieldName('month') eq '' && $self->_getByFieldName('year') eq '' );
    }
    else
    {
        return 0 if( $self->_getByFieldName('dateBegin') eq '');
    }

    if ( $self->albumName || $self->upc || $self->trackName || $self->isrc ) {
        return 1;
    } else {
        # Ignore lines in the footer area
        #
        $self->fail( "Missing product identifier" ) if( $type !~ /Dist Fees/i && $type !~ /Total/i );
    }

    return $self->SUPER::_isValidSaleRecord();
}

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

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

    my $fileName = $args{file}->OrigFileName();

    if( $fileName =~ /_US(_).*\./i )
    {
        $self->{_countryCode}  = 'US';
        $self->{_currencyCode} = 'USD';
    }
    elsif( $fileName =~ /[_\s]C[NA][_\s].*\./i )
    {
        $self->{_countryCode}  = 'CA';
        $self->{_currencyCode} = 'CAD';
    }
    else
    {
        return $self->handleError( "Unable to determine country code from ". $fileName, RPS::DB::Item::SaleImportError::kErrorNonqualifying );
        
    }    

}


## MapFace Stuff

sub _mapFaceServiceID {
	return;
}

sub _mapFaceCountryCode {
	return;
}

sub _mapFaceProductType {
	return ('type');
}

sub _mapFaceFormatType {
	return ('type');
}

sub _mapFaceMediaType {
	return ('type');
}

sub _mapFaceCompatibleVersions {
	return (2,6,14);
}

###
1;# Play nicely.
###
