package RPS::Import::Cadence::v3;

use strict;
use warnings;

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

use Date::Calc qw(Days_in_Month Add_Delta_Days Decode_Month);

use base ( 'RPS::Import::MapFaceBase', 'RPS::Import::ImporterMixed' );

sub physical { 2 }

sub _fieldMapExtended {
    {
        digital => {
            option1 => {
                serviceID   => 'I',
                countryCode => 'L',
                dateBegin   => 'A',
                dateEnd     => 'A',
                productType => 'F',
                formatType  => 'I',
                artistName  => 'C',
                upc         => 'G',
                albumName   => 'D',
                isrc        => 'H',
                trackName   => 'E',
                units       => 'J',
                free        => 'I',
                price       => 'K',
                mediaType   => 'I',
            },
         },
        physical => {
            option1 => {
                dateBegin      => 'A',
                dateEnd        => 'A',
                productType    => 'D',
                artistName     => 'C',
                upc            => 'E',
                albumName      => 'D',
                sales          => 'F',
                returns        => 'G',
                totalRevenue   => 'L',
                mediaType      => 'D',
            },
        },
    };
}

sub _unverifiedFieldMapExtended {
    {
        physical => {
            option1 => {
                _netUnits  => 'H',
            },
        },
    };
}

sub _headerIdentifierExtended {
    {
        digital => {
            option1 => {
                upc => 'UPC',
            },
        },
        physical => {
            option1 => {
                upc => 'UPC',
            },
        },
    };
}

my %serviceMap = (
    '7digital'                                => Client::Service::DSP_7DIGITAL,
    '8tracks'                                 => Client::Service::DSP_8_TRACKS,
    'alibaba - streaming (ad-supported)'      => Client::Service::DSP_ALIBABA,
    'ami_entertainment - streaming (jukebox)' => Client::Service::DSP_AMI,
    'apple music'                             => Client::Service::DSP_APPLE_MUSIC,
    'audio cloud services'                    => Client::Service::DSP_CADENCE,
    'audio cloud services'                    => Client::Service::DSP_CADENCE,
    'audio track stream portable'             => Client::Service::DSP_CADENCE,
    'audio track stream webcast'              => Client::Service::DSP_CADENCE,
    'audio track stream webcast portable'     => Client::Service::DSP_CADENCE,
    'digital allocations stream (audio)'      => Client::Service::DSP_CADENCE,
    'digital allocations streams (audio)'     => Client::Service::DSP_CADENCE,
    'digital allocations stream (video)'      => Client::Service::DSP_CADENCE,
    'digital allocations streams (video)'     => Client::Service::DSP_CADENCE,
    'digital online aud album permanent'      => Client::Service::DSP_CADENCE,
    'digital online aud track permanent'      => Client::Service::DSP_CADENCE,
    'digital online aud track stream'         => Client::Service::DSP_CADENCE,
    'digital online vid track stream'         => Client::Service::DSP_CADENCE,
    'digital online vid track permanent'      => Client::Service::DSP_CADENCE,
    'user generated content stream'           => Client::Service::DSP_CADENCE,
    'video stream video portable'             => Client::Service::DSP_CADENCE,
    'video cloud services'                    => Client::Service::DSP_CADENCE,
    'deezer'                                  => Client::Service::DSP_DEEZER,
    'google play'                             => Client::Service::DSP_GOOGLE_CLOUD,
    'google play locker'                      => Client::Service::DSP_GOOGLE_CLOUD,
    'hoopla'                                  => Client::Service::DSP_HOOPLA,
    'itunes'                                  => Client::Service::DSP_ITUNES,
    'itunes icloud'                           => Client::Service::DSP_ITUNES_CLOUD,
    'apple music radio'                       => Client::Service::DSP_ITUNES_RADIO,
    'medianet'                                => Client::Service::DSP_MEDIANET,
    'musiwave xbox'                           => Client::Service::DSP_MUSIWAVE,
    'netease - streaming (ad-supported)'      => Client::Service::DSP_NETEASE,
    'pcm'                                     => Client::Service::DSP_PCMTECHNOLOGIES,
    'rhapsody'                                => Client::Service::DSP_REAL,
    'simfy'                                   => Client::Service::DSP_SIMFY,
    'slacker'                                 => Client::Service::DSP_SLACKERINC,
    'soundexchange'                           => Client::Service::DSP_SOUNDEXCHANGE,
    'spotify'                                 => Client::Service::DSP_SPOTIFY,
    'stingray'                                => Client::Service::DSP_STINGRAY_DIGITAL_GROUP,
    'tidal'                                   => Client::Service::DSP_TIDAL,
    'tencent - streaming (ad-supported)'      => Client::Service::DSP_TENCENT,
    'touchtunes - streaming (jukebox)'        => Client::Service::DSP_TOUCHTUNES,
    'vevo'                                    => Client::Service::DSP_VEVO,
    'youtube'                                 => Client::Service::DSP_YOUTUBE,
    'longform video'                          => Client::Service::DSP_CADENCE,
    'audio subscription true up'              => Client::Service::DSP_CADENCE,
    'amazon music unlimited'                  => Client::Service::DSP_AMAZON_MUSIC_UNLIMITED,
    'amazon prime'                            => Client::Service::DSP_AMAZON_PRIME,
    'soundcloud'                              => Client::Service::DSP_SOUNDCLOUD,
    'audio stream true up'                    => Client::Service::DSP_CADENCE,
    'digital aud track stream'                => Client::Service::DSP_CADENCE,
    'uma'                                     => Client::Service::DSP_UMA,
    'telco breakage - audio subscr'           => Client::Service::DSP_TELCO,
    'hungama - streaming (subscription)'      => Client::Service::DSP_HUNGAMA,
    'hungama - streaming (ad-supported)'      => Client::Service::DSP_HUNGAMA,
);

my %physMap = (
    '(2cd' => {
        product_type => RPS::File::Sale::TYPE_DBL_CD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(2cd)' => {
        product_type => RPS::File::Sale::TYPE_DBL_CD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(2cd+dvd)' => {
        product_type => RPS::File::Sale::TYPE_DVD_CD_SET,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    '(2lp' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(2lp black)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(2lp)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(2lp)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(3cd' => {
        product_type => RPS::File::Sale::TYPE_DBL_CD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(4lp)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "(7''lp" => {
        product_type => RPS::File::Sale::TYPE_LP5,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(cd+booklet)' => {
        product_type => RPS::File::Sale::TYPE_CD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(cd+dvd)' => {
        product_type => RPS::File::Sale::TYPE_DVD_CD_SET,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    '(dlx 4lp)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(dlx lp)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(dlx)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(ii)-lp' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(lp' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(lp)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(lp+7""lp)' => {
        product_type => RPS::File::Sale::TYPE_LP5,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    "(lp+7''vyl" => {
        product_type => RPS::File::Sale::TYPE_LP5,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(lp+cd' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(lpx2)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    '(lp+dvd)' => {
        product_type => RPS::File::Sale::TYPE_LP,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
);

my %digMap = (
    'ami_entertainment - streaming (jukebox)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio track stream webcast' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'audio stream true up' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'cma download (album)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital allocations stream (audio)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital allocations stream (video)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital allocations streams (video)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital allocations streams (audio)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud album permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud track permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online aud track stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'digital online vid track permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'digital online vid track stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'download (album)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download (rental)' => {
        format_type => RPS::File::Sale::FORMAT_TETHERED,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download (track)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'download (video)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'netease - streaming (ad-supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'pre-order download (album)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'return cma download (track)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'return download (album)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'return download (track)' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'soundexchange - streaming (radio)' => {
        format_type => RPS::File::Sale::FORMAT_PERFORMANCE,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (ad-supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (cloud)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (free trial)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (locker)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (radio)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (subscription)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'streaming (video)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'su' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'telco breakage - audio subscr' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'tencent - streaming (ad-supported)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'touchtunes - streaming (jukebox)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'user generated content stream' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeAudio,
    },
    'video stream video portable' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video streaming (cloud)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video streaming (free trial)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'video streaming (subscription)' => {
        format_type => RPS::File::Sale::FORMAT_STREAM,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
    'permanent' => {
        format_type => RPS::File::Sale::FORMAT_DOWNLOAD,
        media_type => RPS::DB::Item::MediaType::kMediaTypeVideo,
    },
);

my $RE_TYPES_PHYS   = join( '|', map { "\Q$_\E" } sort { $b cmp $a } keys %physMap );
my $RE_SERVICES_DIG = join( '|', map { "\Q$_\E" } sort { $b cmp $a } keys %serviceMap );
my $RE_TYPES_DIG    = join( '|', map { "\Q$_\E" } sort { $b cmp $a } keys %digMap );

sub currencyCode { 'CAD' }
sub channel      { RPS::File::Sale::CHANNEL_RETAIL }
sub priceLevel   { RPS::File::Sale::PLEVEL_UNKNOWN }

sub serviceID {
    my $self = shift;

    # physical
    return Client::Service::DSP_CADENCE if $self->dataType() eq 'physical';

    # digital
    my $serviceStr = lc( $self->_getByFieldName('serviceID') || '' );
    # first try using static services
    if ( my ($service) = $serviceStr =~ /^($RE_SERVICES_DIG).*/i ) {
        return $serviceMap{$service} if exists $serviceMap{$service};
    }
    # second try using services of the system
    if ( my ($service) = $serviceStr =~ /(.+)\s?\-.*/ ) {
        my $serviceID = $self->getServiceID( lc($service) ) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $service };
        return $serviceID if ($serviceID);
    }

    return $self->handleError( "Unable to determine service_name from '$serviceStr'.", RPS::DB::Item::SaleImportError::kErrorService );
}

sub countryCode {
    my $self = shift;

    # physical
    return 'CA' if $self->dataType() eq 'physical';

    # digital
    my $name = $self->_getByFieldName('countryCode') || 'CA';
    return 'CA' if $name =~ /unknown/i;
    return 'BA' if $name =~ /Bosnia & Herzegovina/i;

    my $oCountry = Common::Country->Get($name);
    return $oCountry ? $oCountry->alpha2() : $name;

    $self->fail("Unable to determine country_code from '$name'.");
}

sub saleDates {
    my $self = shift;

    my $startDate = $self->_getByFieldName('dateBegin') || '';
    if ( my ($year, $month) = $startDate =~ m/^(\d{4})[\/_-](\d{1,2})$/ ) {
        return $self->_getDates( date_begin => sprintf( "%04d-%02d-%02d", $year, $month, 1 ) );
    }

    $self->fail("Unable to determine date_begin from '$startDate'.");
}

sub productType {
    my $self = shift;

    my $productStr = lc( $self->_getByFieldName('productType') || '' );

    # physical
    if ( $self->dataType() eq 'physical' ) {
        my ($type) = $productStr =~ /($RE_TYPES_PHYS)/i;
        return RPS::File::Sale::TYPE_CD unless $type;
        return $physMap{$type}{product_type} if exists $physMap{$type};
    }

    # digital
    return RPS::File::Sale::TYPE_ALBUM if $productStr =~ /^\s*Album\s*$/i;
    return RPS::File::Sale::TYPE_TRACK if $productStr =~ /^\s*Tracks & other downloads\s*$/i;

    $self->fail("Unable to determine product_type from an empty value.") unless $productStr;

    return $self->handleError( "Unable to determine product_type from '$productStr'.", RPS::DB::Item::SaleImportError::kErrorProductType );
}

sub formatType {
    my $self = shift;

    my $formatStr = lc( $self->_getByFieldName('formatType') || '' );
    if ( my ($type) = $formatStr =~ /($RE_TYPES_DIG)/i ) {
        return $digMap{$type}{format_type} if exists $digMap{$type};
    }

    return $self->handleError( "Unable to determine format_type from '$formatStr'.", RPS::DB::Item::SaleImportError::kErrorFormatType );
}

sub mediaType {
    my $self = shift;

    my $mediaStr = lc( $self->_getByFieldName('mediaType') || '' );

    # physical
    if ( $self->dataType() eq 'physical' ) {
        my ($type) = $mediaStr =~/($RE_TYPES_PHYS)/i;
        return RPS::DB::Item::MediaType::kMediaTypeAudio unless $type;
        return $physMap{$type}{media_type} if exists $physMap{$type};
    }

    # digital
    if ( my ($type) = $mediaStr =~/($RE_TYPES_DIG)/i ) {
        return $digMap{$type}{media_type} if exists $digMap{$type};
    }

    return $self->handleError( "Unable to determine media_type from '$mediaStr'.", RPS::DB::Item::SaleImportError::kErrorMediaType );
}

sub free {
    my $self = shift;

    return 0 if $self->dataType() eq 'physical';

    my $formatStr = lc( $self->_getByFieldName('formatType') || '' );
    if ( !$self->price && $formatStr =~ /Streaming \(Free Trial\)/i ) {
        return 1;
    }
}

sub albumName {
    my $self = shift;

    my $albumStr = $self->_getByFieldName('albumName') || '';

    # physical
    if ( $self->dataType() eq 'physical' ) {
        $albumStr =~ s/(?:$RE_TYPES_PHYS)//i;
        return $albumStr;
    }

    return $albumStr;
}

# digital
sub price     { abs( shift->_getByFieldName('price') || 0 ) }
sub unitPrice { abs shift->SUPER::unitPrice }
sub units {
    my $self = shift;

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

    if ( $price > 0 ) {
        $units = $units ? abs($units) : 1;
    } elsif ( $price < 0 ) {
       $units = $units ? -1 * abs($units) : -1;
    }

    return $units;
}

# physical
sub totalRevenue   { $_[0]->_getByFieldName('totalRevenue') || 0 }
sub salesRevenue   { $_[0]->totalRevenue > 0 ? $_[0]->totalRevenue     : 0 }
sub returnsRevenue { $_[0]->totalRevenue < 0 ? abs $_[0]->totalRevenue : 0 }

sub sales {
    my $self = shift;

    my $sales = $self->_getByFieldName('sales')        || 0;
    my $returns = $self->_getByFieldName('returns')    || 0;
    my $netUnits = $self->_getByFieldName('_netUnits') || 0;
    if ( !$sales && !$returns && !$netUnits ) {
        $sales = 1;
    }

    return abs $sales;
}

sub returns {
    my $self = shift;

    my $sales = $self->_getByFieldName('sales')        || 0;
    my $returns = $self->_getByFieldName('returns')    || 0;
    my $netUnits = $self->_getByFieldName('_netUnits') || 0;
    if ( !$sales && !$returns && !$netUnits ) {
        $returns = 1;
    }

    return abs $returns;
}

sub netUnits {
    my $self = shift;

    return $self->_getByFieldName('_netUnits') || 0;
}

sub _isValidSaleRecord {
    if ( $_[0]->dataType() eq 'physical' ) {

        my $sales    = $_[0]->sales;
        my $returns  = $_[0]->returns;
        my $netUnits = $_[0]->_getByFieldName('_netUnits') || 0;
        if ( $sales - $returns != $netUnits ) {
            $_[0]->fail("Sales ($sales) - Returns ($returns) is not equal to Net Units ($netUnits).");
        }

        return ($_[0]->_getByFieldName('albumName') || $_[0]->_getByFieldName('artistName')) &&
               ($_[0]->_getByFieldName('sales') || $_[0]->_getByFieldName('returns') || $_[0]->_getByFieldName('totalRevenue') )
    }

    return $_[0]->_getByFieldName('albumName') || $_[0]->_getByFieldName('artistName');
}

#####    MapFace    #####

sub _mapFaceServiceID {
    return ('serviceID');
}

sub _mapFaceCountryCode {
    return ('countryCode');
}

sub _mapFaceProductType {
    return ('productType');
}

sub _mapFaceFormatType {
    return ('formatType');
}

sub _mapFaceMediaType {
    return ('mediaType');
}

1;
