package RPS::Import::MusicNet;

use strict;


use Date::Calc qw(Days_in_Month Decode_Month);

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

use lib '/app/tools/data_classes/lib';
use Client::Service;

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

my %field_map = (
                 1 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'upc'       => 2,
                        'album'     => 3,
                        'artist'    => 4,
                        'isrc'      => 5,
                        'units'     => 6,
                        'prodtype'  => 7,
                        'label'     => 8,
                        'tracknum'  => 9,
                        'clientid'  => 11,
                        'retailer'  => 12,
                        'category'  => 13,
                        },
                 2 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'album'     => 3,
                        'artist'    => 4,
                        'upc'       => 5,
                        'isrc'      => 6,
                        'units'     => 7,
                        'prodtype'  => 8,
                        'label'     => 9,
                        'tracknum'  => 12,
                        },
                 3 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'album'     => 3,
                        'artist'    => 4,
                        'upc'       => 5,
                        'isrc'      => 6,
                        'units'     => 7,
                        'prodtype'  => 8,
                        'label'     => 9,
                        'tracknum'  => 13,
                        },
                 4 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'album'     => 3,
                        'artist'    => 4,
                        'upc'       => 5,
                        'isrc'      => 6,
                        'units'     => 7,
                        'prodtype'  => 8,
                        'label'     => 9,
                        'tracknum'  => 13,
                        },
                 5 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'upc'       => 2,
                        'album'     => 3,
                        'artist'    => 4,
                        'isrc'      => 5,
                        'units'     => 6,
                        'prodtype'  => 7,
                        'label'     => 8,
                        'tracknum'  => 9,
                        'clientid'  => 11,
                        'retailer'  => 12,
                        'category'  => 13,
                        'country'   => 15,
                        'currency'  => 16,
                        },
                        6 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'album'     => 3,
                        'artist'    => 4,
                        'upc'       => 5,
                        'isrc'      => 6,
                        'units'     => 7,
                        'prodtype'  => 8,
                        'label'     => 9,
                        'tracknum'  => 12,
                        'country'   => 14,
                        'currency'  => 15,
                        },  
                        7 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'upc'       => 2,
                        'album'     => 3,
                        'artist'    => 4,
                        'isrc'      => 5,
                        'units'     => 6,
                        'prodtype'  => 7,
                        'label'     => 8,
                        'tracknum'  => 9,
                        'clientid'  => 11,
                        'retailer'  => 12,
                        'category'  => 13,
                        'country'   => 15,
                        'currency'  => 16,
                        'price'     => 17,
                        },  
                        8 => {
                        'vendorid'  => 0,
                        'track'     => 1,
                        'upc'       => 2,
                        'album'     => 3,
                        'artist'    => 4,
                        'isrc'      => 5,
                        'units'     => 6,
                        'prodtype'  => 7,
                        'label'     => 8,
                        'tracknum'  => 9,
                        'clientid'  => 11,
                        'retailer'  => 12,
                        'category'  => 13,
                        'country'   => 15,
                        },                                                                            
                );

my %currency_map = (
    US  => 'USD',
    CA  => 'USD',
    GB  => 'GBP',
    DE  => 'GBP',
    FR  => 'GBP',
                   );
                   
my %service_map = (
    "DigitalMedia 2.0"        => Client::Service::DSP_DIGITAL_MEDIA_2_0,
    "DigitalMedia Canada 2.0" => Client::Service::DSP_DIGITAL_MEDIA_2_0,
    "DigitalMedia GB 2.0"     => Client::Service::DSP_DIGITAL_MEDIA_2_0,
    "MOG Australia"           => Client::Service::DSP_MOG,
    "DMGB"                    => Client::Service::DSP_DMGB,
);



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

#public methods

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

	my $retval = undef;
	my $lines = $args{lines};
	my $fileObj = $args{file};
	my $fileName = $fileObj->OrigFileName;
    my $version = $fileObj->VersionNum;

    return undef unless ($lines && $fileName && $version);

    my $offsets = $field_map{$version};

    ## category only applies to version 1, so everything using it
    ## will only be applied if category field is present in file
    my $loggableCategory = '^(NORMAL|TRIAL)$';

    my ($countryCode, $dateBegin, $dateEnd);
    if ($version == 1 && $fileName =~ m/^(GB|US|CA)?.*(20\d\d-\d\d-01)_(20\d\d-\d\d-\d\d)/) {
        ($countryCode, $dateBegin, $dateEnd) = ($1,$2,$3);
    } elsif($fileName =~ m/BPMediaNet(\w{3})(\d{2})(Tracks|Albums|Streams)/) {
        my $year = $2+2000;
        my $month = Decode_Month($1);
        $dateBegin = $year."-".$month."-1";
        $dateEnd = $year."-".$month."-".Days_in_Month($year,$month);
    } elsif ($fileName =~ m/(\d\d)(\d\d)(\d{4})_(\d\d)(\d\d)(\d{4})/) {
            $dateBegin = $3."-".$1."-".$2;
            $dateEnd   = $6."-".$4."-".$5;
    } elsif ($fileName =~ m/(20\d\d-\d\d-01)[ |_](20\d\d-\d\d-\d\d)/) {
            $dateBegin = $1;
            $dateEnd   = $2;
    } elsif ($fileName =~ m/(\w+) (20\d\d) PD\.(xls|csv|txt)/i) {
        my $year = $2;
        my $month = Decode_Month($1);
        $dateBegin = $year."-".sprintf("%02d",$month)."-01";
        $dateEnd = $year."-".sprintf("%02d",$month)."-".Days_in_Month($year,$month);
        $countryCode = "US";
    } elsif ($fileName =~ m/(20\d\d) (\w+) (\w+)\.(xls|csv|txt)/i) {
        my $year = $1;
        my $month = Decode_Month($2);
        $dateBegin = $year."-".sprintf("%02d",$month)."-01";
        $dateEnd = $year."-".sprintf("%02d",$month)."-".Days_in_Month($year,$month);
        $countryCode = "US";
    } elsif ($fileName =~ m/(20\d\d) (\w+)\.(xls|csv|txt)/i) {
        my $year = $1;
        my $month = Decode_Month($2);
        $dateBegin = $year."-".sprintf("%02d",$month)."-01";
        $dateEnd = $year."-".sprintf("%02d",$month)."-".Days_in_Month($year,$month);
        $countryCode = "US";
    }

	unless ($dateBegin && $dateEnd) {
        $self->errstr("couldn't get dates");
        print STDERR "filename: $fileName\n";
        return undef;
    }

	my $currencyCode;
    my %errors = ();
	my $linenum = 1;

	foreach my $line(@$lines)
	{
		if ($linenum == 1) {
            $linenum++;
            next;
        }

		my $prodtype;
		my $format;

		if ($line->[$offsets->{'prodtype'}] =~ /streams/i &&
            ## only check if category present in this version
            (!(defined $offsets->{'category'}) || $line->[$offsets->{'category'}] =~ m/$loggableCategory/i))
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_STREAM;
		}
		if ($line->[$offsets->{'prodtype'}] =~ m/^Play ?Counts$/i &&
            ## only check if category present in this version
            (!(defined $offsets->{'category'}) || $line->[$offsets->{'category'}] =~ m/$loggableCategory/i))
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_TETHERED;
		}
		if ($line->[$offsets->{'prodtype'}] =~ /Device Play Counts/i &&
            ## only check if category present in this version
            (!(defined $offsets->{'category'}) || $line->[$offsets->{'category'}] =~ m/$loggableCategory/i))
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_TETHERED;
		}
		elsif ($line->[$offsets->{'prodtype'}] =~ m/^Permanent Albums$/i)
		{
			$prodtype	= RPS::File::Sale::TYPE_ALBUM;
			$format		= RPS::File::Sale::FORMAT_DOWNLOAD;
		}
        elsif ($line->[$offsets->{'prodtype'}] =~ /Permanent MP3 Albums/i) {
            $prodtype   = RPS::File::Sale::TYPE_ALBUM;
            $format     = RPS::File::Sale::FORMAT_DOWNLOAD;
        }
        elsif ($line->[$offsets->{'prodtype'}] =~ /Permanent MP3 A la Carte Tracks/i)
        {
            $prodtype   = RPS::File::Sale::TYPE_TRACK;
            $format     = RPS::File::Sale::FORMAT_DOWNLOAD;
        }
		elsif ($line->[$offsets->{'prodtype'}] =~ m/^Permanent A ?la Carte Tracks$/i)
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_DOWNLOAD;
		}
		elsif ($line->[$offsets->{'prodtype'}] =~ m/^Permanent Album Tracks$/i)
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_DOWNLOAD;
		}
		elsif ($line->[$offsets->{'prodtype'}] =~ m/^Permanent Downloads$/i)
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_DOWNLOAD;
		}
		elsif ($line->[$offsets->{'prodtype'}] =~ m/^Permanent Subscription Token Tracks$/i)
		{
			$prodtype	= RPS::File::Sale::TYPE_TRACK;
			$format		= RPS::File::Sale::FORMAT_DOWNLOAD;
		}

		my $vendorID	= $line->[$offsets->{'vendorid'}];
		my $clientID	= ($offsets->{'clientid'})?$line->[$offsets->{'clientid'}]:undef;
		my $upc			= Common::Util::normalize_upc($line->[$offsets->{'upc'}]);
		my $isrc		= Common::Util::normalize_isrc($line->[$offsets->{'isrc'}]);
		my $artist		= $line->[$offsets->{'artist'}];
		my $album		= $line->[$offsets->{'album'}];
		my $track		= $line->[$offsets->{'track'}];
		my $label		= $line->[$offsets->{'label'}];
		my ($tracknum)	= $line->[$offsets->{'tracknum'}] =~ m/^(\d+)$/;
		my ($units)		= $line->[$offsets->{'units'}] =~ m/^(-?\d+)$/;
		
		my $price	    = ($offsets->{'price'})?$line->[$offsets->{'price'}]:undef;

        if( defined $offsets->{country} )
        {
            $countryCode = $line->[$offsets->{'country'}];

            if ($version == 8)
            {
                $currencyCode = 'USD';
            }
            else
            {
                if( $countryCode eq "" )
                {
                    $currencyCode = Common::Client::Current()->Locale()->currencyFormat()->currencyCode();
                }
                else
                {
                    my $currencyFormat = Common::CurrencyFormat->new(countryCode => $countryCode);
                    $currencyCode = $currencyFormat->currencyCode();
                }
            }
        }

		my $free = 0;
        ## only check category if version 1
		$free = 1 if ((defined $offsets->{'category'}) and $line->[$offsets->{'category'}] =~ m/^TRIAL$/i and
                     ($format eq RPS::File::Sale::FORMAT_STREAM or $format eq RPS::File::Sale::FORMAT_TETHERED));
        #$free = 1 if(defined $offsets->{'category'} && $line->[$offsets->{'category'}] =~ /trial/i);

		if ($prodtype && $units && ($artist || $album || $track))
		{
            unless ($currencyCode ne "" && $countryCode ne "") {
                $self->errstr("Could not find country/currency: ".$countryCode . " line:".$linenum);
                print STDERR "Could not find country/currency: ".$countryCode . " line:".$linenum."\n";
                return undef;
            }

            my $serviceID;
            if (defined $offsets->{retailer})
            {
                my $serviceName = $line->[$offsets->{retailer}];
                $serviceName =~ s/\s+(US|CANADA|CA|UK|FR|DE)$//i;
                
                $serviceID = $self->_get_service_id($serviceName);
                
                if(!$serviceID){
                    $serviceID = $service_map{$serviceName};
                }
                
                unless ($serviceID)
                {
                    unless ($errors{$serviceName})
                    {
                        die "unknown service '$serviceName', line:$linenum";
                    }
                }
            }

            my $sale = RPS::Import::SaleRec->new();

			$sale->serviceID($serviceID) if $serviceID;
			$sale->productType($prodtype);
			$sale->formatType($format);
			$sale->dateBegin($dateBegin);
			$sale->dateEnd($dateEnd);
			$sale->serviceProductID($vendorID);
			$sale->clientProductID($clientID);
			$sale->upc($upc);
			$sale->isrc($isrc);
			$sale->artistName($artist);
			$sale->albumName($album);
			$sale->trackName($track);
			$sale->labelName($label);
			$sale->trackNum($tracknum);
			$sale->units($units);
			$sale->currencyCode($currencyCode);
			$sale->countryCode($countryCode);
			$sale->lineNum($linenum);
			$sale->free($free);
			$sale->price($price);

			$self->_insertSale(sale => $sale);
        } #else { print STDERR "skip l: $linenum p: $prodtype u: $units r: $artist a: $album t: $track\n" . join(",",@$line) . "\n"; }
		$linenum++;
	}

	return $linenum;
}

#
# Private methods
#

sub _get_service_id
{
    my $self = shift;
    my $serviceName = lc shift;

    # minor adjustments to help the decorated service name match ours
    $serviceName =~ s/mtvn/mtv_networks/;

    return $self->getServiceID($serviceName) || $RPS::Import::ServiceMap::SERVICE_ALIASES{ lc $serviceName };;
}

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