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

package RPS::Import::Tunecore::v2;

use strict;

use Math::BigFloat;

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

use lib '/app/tool/common/lib';
use Common::Country;

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

sub _fieldMap {
    {
        labelName     => 'I',
        serviceID     => 'C',
        countryCode   => 'D',
        dateBegin     => 'A',
        dateEnd       => 'A',
        productType   => 'F',
        formatType    => 'N',
        artistName    => 'E',
        upc           => 'J',
        albumName     => 'G',
        isrc          => 'M',
        trackName     => 'H',
        units         => 'O',
        price         => 'T',
	}
}

sub _unverifiedFieldMap {
    {
        optionalUPC   => 'K',
        netSales      => 'Q',
        exchRate      => 'S',
        currency      => 'U',
    }
}


my %formatTypes = (
    'download'              => RPS::File::Sale::FORMAT_DOWNLOAD,
    'streaming'             => RPS::File::Sale::FORMAT_STREAM,
);


sub _headerIdentifier { ( labelName => 'Label' ) }

sub currencyCode{ 'USD' }

sub mediaType {
    my $self = shift;
    my $value = $self->_getByFieldName( 'productType' );

    if($value && $value =~ /^(song|album)$/i)
    {
        return RPS::DB::Item::MediaType::kMediaTypeAudio;
    }
    elsif($value && $value =~ /^video$/i )
    {
        return RPS::DB::Item::MediaType::kMediaTypeVideo;
    }
    $self->fail("Unable to determine media type from '$value'");
}

sub upc {
    my $self = shift;

    # Use optionalUPC as primary, with upc as backup (FB10706).
    #
    my $upc = $self->_getByFieldName('optionalUPC');
    if( !$upc || '' eq $upc )
    {
        $upc = $self->_getByFieldName('upc');
    }
    return $upc;
}

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

	if( $value && $value =~ /^album$/i )
    {
		return RPS::File::Sale::TYPE_ALBUM;

	}
    elsif ( $value && $value =~ /^(song|video)$/i )
    {
		return RPS::File::Sale::TYPE_TRACK;
	}
    $self->fail( "Unknown product type '$value'" ); 	    
}

sub formatType {
	my $self = shift;
	my $value = $self->_getByFieldName( 'formatType' );
	
    my $formatType = $formatTypes{lc($value)};
    
    $self->fail( "Unknown format type '$value'" ) unless $formatType;  
    
    return $formatType; 
}


sub serviceID {
    my $self = shift;
    my $serviceID;
    my $service = $self->_getByFieldName( 'serviceID' );

    if ( $service )
    {
        my $serviceClean = $service;
        $serviceClean =~ s/ \(\w{2}\)//;
        $serviceID = $self->getServiceID( $serviceClean ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $serviceClean };
    }

    $self->fail( "Unknown service '$service'" ) unless( $serviceID );

    return $serviceID;
}

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

    # The 'sign' of the units is driven by the price.
    # If the price is negative, we'll store negative units,
    # regardless of whether the units were positive or negative
    # in the sale file.  Accordingly, the price is always
    # positive.  This ensures that returns are recorded correctly.
    #
    if( defined($price) ) {
        return $price < 0 ? abs($units) * -1 : $units;
    }
    else {
        return $units;
    }
}

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

sub _validateSaleRec
{
    my ($self, $saleRec) = @_;

    # Sanity check - was revenue actually converted for non-USD transactions?
    #
    if( 'USD' ne $self->_getByFieldName('currency') )
    {

        my $netSales = $self->_getByFieldName('netSales');
        if( 0 != $netSales && $netSales == $self->_getByFieldName('price') )
        {
            my $exchRate = $self->_getByFieldName('exchRate');

            if( $exchRate )
            {
                my $revenue = Math::BigFloat->new($exchRate * $netSales);  # prevent scientific notation...
                my $revDecimalPlaces = length(($revenue =~ /\.(.*)/)[0]);

                # If the net sales is equal to the total earnings, then check
                # if this is due to the netSales * exchangeRate exceeding Tunecore's
                # number of decimal places (six decimal places -- see Case 14064).
                # If price * exchange rate has more than six decimal places, then
                # allow the sale to be processed (we'll still record the total earnings,
                # but it will be the earnings truncated to six decimal places as
                # reported in the sales file).
                #
                return 1 if( $revDecimalPlaces > 6 );
            }

            # No exchange rate...
            #
            $self->fail("Revenue not converted");

        }
    }

    return $self->SUPER::_validateSaleRec($saleRec);
}

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