package RPS::Import::DRASubset;

use strict;


use Date::Calc qw(Days_in_Month);

use lib '/app/tools/common/lib';
use Common::Util;
use Common::Consts qw(%COUNTRY_CODE);

use Common::RSMath qw(round);

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

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


my %service_map = (
    'apple computer, inc.'  => Client::Service::DSP_ITUNES,
    'virginmega sas'        => Client::Service::DSP_VIRGINMEGA,
    'touch tunes, inc.'     => Client::Service::DSP_TOUCHTUNES,
    'hudson entertainment'  => Client::Service::DSP_HUDSON,
    'buongiorno vitaminic spa'  => Client::Service::DSP_VITAMINIC,
    'mobilestreams'             => Client::Service::DSP_MOBILESTREAMS,
    'orange'                    => Client::Service::DSP_ORANGENEDERLAND,
    'fnac direct'               => Client::Service::DSP_FNAC,
);

my %format_map = (
    'permanent download'     => RPS::File::Sale::FORMAT_DOWNLOAD,
    'subscription play'      => RPS::File::Sale::FORMAT_STREAM,
    'ota'                    => RPS::File::Sale::FORMAT_DOWNLOAD,
    'subscription download'  => RPS::File::Sale::FORMAT_DOWNLOAD,
    'master ringtone'        => RPS::File::Sale::FORMAT_RINGTONE,
    'polyphonic ringtone'    => RPS::File::Sale::FORMAT_RINGTONE,
);

my %field_map = (
    2 => {
        vendor_id   => 0,
        artist      => 1,
        track       => 2,
        album       => 3,
        isrc        => 4,
        upc         => 5,
        date_col    => 7,
        date_row    => 1,
        format_row  => 11,
        service_row => 12,
        start_col   => 37,
    },
);

#public methods

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

	my $lines = $args{lines};
	my $fileObj = $args{file};
    my $version = $fileObj->VersionNum;
    #my $version = $args{version}; ## for cmd-line testing

    my $offsets = $field_map{$version};

    return undef unless ($lines);
	my ($dateBegin, $dateEnd) = $self->_getDates($lines->[$offsets->{'date_row'}]->[$offsets->{'date_col'}]);
    unless ($dateBegin && $dateEnd) {
        $offsets->{'date_row'}++;
        ($dateBegin, $dateEnd) = $self->_getDates($lines->[$offsets->{'date_row'}]->[$offsets->{'date_col'}]);
    }
    
	unless ($dateBegin && $dateEnd) {
        $self->errstr("couldn't get dates from ".$lines->[$offsets->{'date_row'}]->[$offsets->{'date_col'}]);
        return undef;
    }

    my %errors;
    my @columns;

    my $start_col = 0;
    FIND_START: while ($start_col < 300) {
        foreach my $format (keys %format_map) {
            if (lc $lines->[$offsets->{'format_row'}]->[$start_col] eq $format) {
                last FIND_START;
            }
        }
        $start_col++;
    }
    
    my $format;
    for (my $i = $start_col; $lines->[$offsets->{'service_row'}]->[$i] ne ""; $i += 2)
    {
        if ($lines->[ $offsets->{'format_row'} ]->[$i] ne "")
        {
            $format = $format_map{ lc $lines->[ $offsets->{'format_row'} ]->[$i] };
            unless ($format)
            {
                unless ($errors{$lines->[ $offsets->{'format_row'} ]->[$i]})
                {
                    print STDERR "unknown format: " . $lines->[ $offsets->{'format_row'} ]->[$i] . "\n";
                    $errors{$lines->[ $offsets->{'format_row'} ]->[$i]} = 1;
                }
                $self->warning();
                next;
            }
        }

        $columns[$i]->{format} = $format;
        ($columns[$i]->{service}, $columns[$i]->{country}) = $self->_parseService($lines->[ $offsets->{'service_row'} ]->[$i]);
        unless ($columns[$i]->{service})
        {
            unless ($errors{$lines->[ $offsets->{'service_row'} ]->[$i]})
            {
                print STDERR "unknown service: " . $lines->[ $offsets->{'service_row'} ]->[$i] . "\n";
                $errors{$lines->[ $offsets->{'service_row'} ]->[$i]} = 1;
            }
            $self->warning();
            next;
        } 
    }


    my $linenum = 0;
    foreach my $line(@$lines)
    {
        $linenum++;
        next unless ($linenum > $offsets->{'service_row'} + 1);

        my $ptype     = RPS::File::Sale::TYPE_TRACK;
        my $artist    = $line->[$offsets->{'artist'}];
        my $album     = $line->[$offsets->{'album'}];
        my $track     = $line->[$offsets->{'track'}];
        my $vendor_id = $line->[$offsets->{'vendor_id'}];
        my $upc       = Common::Util::normalize_upc($line->[$offsets->{'upc'}]);
        my $isrc      = Common::Util::normalize_isrc($line->[$offsets->{'isrc'}]);

        #for (my $col = $offsets->{'start_col'}; $lines->[$offsets->{'service_row'}]->[$col] ne ""; $col += 2) {
        for (my $col = $start_col; $lines->[$offsets->{'service_row'}]->[$col] ne ""; $col += 2) {

            my $format  = $columns[$col]->{format};
            my $service = $columns[$col]->{service};
            my $country = $columns[$col]->{country};

            my $units = $line->[$col];
            my $price = $line->[$col + 1];

            $price =~ s/^\$//g;

            $price = ($units != 0)? round($price / $units,8):0;

            if ($units && $track && $artist && $album && $service && $country && $format) {
                my $sale = RPS::Import::SaleRec->new();

                $sale->serviceID($service);
                $sale->productType($ptype);
                $sale->formatType($format);
                $sale->dateBegin($dateBegin);
                $sale->dateEnd($dateEnd);
                $sale->serviceProductID($vendor_id);
                $sale->upc($upc);
                $sale->isrc($isrc);
                $sale->artistName($artist);
                $sale->albumName($album);
                $sale->trackName($track);
                $sale->units($units);
                $sale->price($price);
                $sale->lineNum($linenum);
                $sale->countryCode($country);

                #$args{dumper}($sale); # for cmd-line testing
                $self->_insertSale(sale => $sale);
            }
        }
    }
    return $linenum;
}


#
# Private methods
#

sub _getDates
{
	my $self = shift;
	my $date = shift;

	my ($dateBegin, $dateEnd);

    if ($date =~ m/^(\d{4})-(\d?\d)-(\d?\d) to (\d{4})-(\d?\d)-(\d?\d)$/) {
                my ($dateBegin, $dateEnd) = 
                $self->
                SUPER::_getDates(date_begin=>sprintf("%04d-%02d-%02d", $1, $2, $3),
                                 date_end=>sprintf("%04d-%02d-%02d", $4, $5, $6),
                                 type=>"iso");
                                 
                return ($dateBegin, $dateEnd);
    }

    return undef;
}

sub _parseService
{
    my $self = shift;
    my $serviceCell = lc shift;

    my $country;
    foreach my $cc(keys %COUNTRY_CODE)
    {
        if ($serviceCell =~ s/\s+\(?$cc\)?$//)
        {
            $country = $COUNTRY_CODE{$cc};
            last;
        }
    }

    if ($serviceCell =~ s/\s+s\.a\.r\.l\.$//)
    {
        $country = 'EU';
    }
    else
    {
        $country ||= 'US';
    }

    # if country _is_ present and doesn't match anything in %COUNTRY_CODE then it'll remain part of the
    # service name and won't be identified in the following statement - so it will still get caught
    return (
        $self->getServiceID($serviceCell) || $service_map{$serviceCell},
        $country,
    );
}

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