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

package RPS::Import::AmazonMusicUnlimited;

use strict;

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

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

sub _fieldMap {
    my $self = shift;

    my %fieldMap = (
        1 => {
            labelName        => 'L',
            countryCode      => 'M',
            dateBegin        => 'P',
            serviceProductID => 'A',
            upc              => 'C',
            artistName       => 'I',
            isrc             => 'E',
            albumName        => 'J',
            trackName        => 'K',
            currencyCode     => 'M',
            price            => 'N',
        },
        2 => {
            labelName        => 'O',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'N',
            upc              => 'L',
            albumName        => 'M',
            isrc             => 'H',
            trackName        => 'J',
            currencyCode     => 'B',
            price            => 'Q',
        },
        3 => {
            labelName        => 'O',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'N',
            upc              => 'L',
            albumName        => 'M',
            isrc             => 'H',
            trackName        => 'J',
            units            => 'F',
            currencyCode     => 'B',
            price            => 'Q',
        },
        4 => {
            labelName        => 'P',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'O',
            upc              => 'M',
            albumName        => 'N',
            isrc             => 'H',
            trackName        => 'J',
            units            => 'F',
            currencyCode     => 'B',
            price            => 'R',
        },
        5 => {
            labelName        => 'O',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'N',
            upc              => 'L',
            albumName        => 'M',
            isrc             => 'H',
            trackName        => 'J',
            units            => 'F',
            currencyCode     => 'B',
            price            => 'Q',
        },
        99 => {
            labelName        => 'O',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'N',
            upc              => 'L',
            albumName        => 'M',
            isrc             => 'H',
            trackName        => 'J',
            units            => 'F',
            currencyCode     => 'T',
            price            => 'Q',
        },
        100 => {
            labelName        => 'P',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'O',
            upc              => 'M',
            albumName        => 'N',
            isrc             => 'I',
            trackName        => 'K',
            units            => 'F',
            currencyCode     => 'U',
            price            => 'R',
        },
        102 => {
            labelName        => 'O',
            countryCode      => 'B',
            dateBegin        => 'A',
            serviceProductID => 'G',
            artistName       => 'N',
            upc              => 'L',
            albumName        => 'M',
            isrc             => 'H',
            trackName        => 'J',
            units            => 'F',
            currencyCode     => 'U',
            price            => 'Q',
        },
    );

    return $fieldMap{ $self->_version };
}

sub _unverifiedFieldMap {
    my $self = shift;

    my %fieldMap = (
        1 => {
            downloadPlays  => 'G',
            streamingPlays => 'H',
        },
        2 => {
            downloadPlays  => 'E',
            streamingPlays => 'D',
        },
        3 => {
            downloadPlays  => 'E',
            streamingPlays => 'D',
        },
        4 => {
            downloadPlays  => 'E',
            streamingPlays => 'D',
        },
        5 => {
            downloadPlays  => 'E',
            streamingPlays => 'D',
        },
        99 => {
            downloadPlays      => 'E',
            streamingPlays     => 'D',
        },
        100 => {
            downloadPlays  => 'E',
            streamingPlays => 'D',
        },
        102 => {
            downloadPlays      => 'E',
            streamingPlays     => 'D',
        },
    );

    return $fieldMap{ $self->_version };
}

sub _headerIdentifier { artistName => 'artist name' }
sub mediaType         { RPS::DB::Item::MediaType::kMediaTypeAudio }
sub productType       { RPS::File::Sale::TYPE_TRACK }

sub serviceID {
    my $self = shift;

    return $self->SUPER::serviceID if $self->_version != 99;

    my $fileName = $self->filename;
    return Client::Service::DSP_AMAZON_MUSIC_UNLIMITED if $fileName =~ /AMU/i;
    return Client::Service::DSP_AMAZON_PRIME           if $fileName =~ /Prime/i;

    return Client::Service::DSP_AMAZON;
}

sub upc {
    my $self = shift;

    my $upc = $self->_getByFieldName('upc') || '';
    $upc *= 1 if $upc =~ /E[+-]/i;
    return Common::Util::normalize_upc($upc);
}

sub isrc {
    my $self = shift;
    return Common::Util::normalize_isrc( $self->_getByFieldName('isrc') );
}

sub saleDates {
    my $self = shift;

    my $dt = $self->_getByFieldName('dateBegin') || '';
    if ( $dt =~ /^(\d{4})(\d{2})$/ ) {
        $dt = sprintf( "%04d-%02d-01", $1, $2 );
    }

    return $self->_getDates( date_begin => $dt );
}

# The following accessors are used in our parent's (SUPER) _saveLine
#
sub formatType {
    return shift->{_formatType};    # set in _saveLine (below)
}

sub unitPrice {
    return shift->{_unitPrice};     # set in _saveLine (below)
}

sub units {
    return shift->{_units};         # set in _saveLine (below)
}

# We can have units from two different columns so we need to override
# _isValidSaleRecord to process lines with units in either location.
#
sub _isValidSaleRecord {
    my $self           = shift;
    my $downloadPlays  = $self->_getByFieldName('downloadPlays');
    my $streamingPlays = $self->_getByFieldName('streamingPlays');
    return ( ( $downloadPlays || $streamingPlays ) && ( $self->trackName || $self->albumName ) );
}

# By default, _saveLine will create a single sale record.  Amazon may
# have multiple sales per line (streams and/or tethered).  To accomodate
# these we'll override _saveLine and create multiple sales records as
# needed.
#
sub _saveLine {
    my $self = shift;

    my $downloadPlays  = $self->_getByFieldName('downloadPlays');
    my $streamingPlays = $self->_getByFieldName('streamingPlays');
    my $price          = $self->price;

    # revenue is applied evenly to all units
    my $unitPrice = $price / ( $downloadPlays + $streamingPlays );

    # only for the versions 3, 4 and 5
    if ( $self->_version =~ /^(?:3|4|5)$/ ) {
        $self->{_formatType} = RPS::File::Sale::FORMAT_STREAM;
        $self->{_units}      = $downloadPlays + $streamingPlays;
        $self->{_unitPrice}  = $unitPrice;
        $self->SUPER::_saveLine();
        return 1;
    }

    if ( $downloadPlays ) {
        $self->{_formatType} = RPS::File::Sale::FORMAT_TETHERED;
        $self->{_units}      = $downloadPlays;
        $self->{_unitPrice}  = $unitPrice;
        $self->SUPER::_saveLine();
    }

    if ( $streamingPlays ) {
        $self->{_formatType} = RPS::File::Sale::FORMAT_STREAM;
        $self->{_units}      = $streamingPlays;
        $self->{_unitPrice}  = $unitPrice;
        $self->SUPER::_saveLine();
    }
}

sub currencyCode {
    my $self = shift;

    my $code = $self->_getByFieldName("currencyCode") || '';

    if ( $self->_version =~ /^(?:3|4|5)$/ && $self->filename=~ /USD\.\w+$/i ) {
        return 'USD';
    } elsif ( $self->_version =~ /^(?:99|102)$/ ) {
        return $code;
    }

    # exception
    return 'ISK' if $code =~ /^IS$/i;

    # versions: 1, 2, 3, 4, 5
    # determine currency code from 2-letter country code
    my $oCurrencyFmt = Common::CurrencyFormat->new( countryCode => $code );
    return $oCurrencyFmt->currencyCode() if $oCurrencyFmt;

    $self->fail("Unable to determine country code from '$code'");
}


1;
