package RPS::Import::IODA;

use strict;

use Date::Calc qw(Days_in_Month Decode_Month);

use lib '/app/tools/common/lib';
use Common::Util;
use Common::Consts;

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 = (
    'RealNetworks / Rhapsody' => Client::Service::DSP_REAL,
    'MSN Music Service'       => Client::Service::DSP_MSNMUSIC,
    'iTunes Music Store'      => Client::Service::DSP_ITUNES,
);

## not 100% sure what all is used in the IODA format...
my %ioda_countries = (
    'USA' => 'US',
    'GBR' => 'GB',
    'CAN' => 'CA',
);
my %ioda_formats = (
    'Permanent Restricted Download' => RPS::File::Sale::FORMAT_DOWNLOAD,
    'On-Demand Stream'              => RPS::File::Sale::FORMAT_STREAM,
);

use constant FIELD_SERVICE => 0;
use constant FIELD_COUNTRY => 1;
use constant FIELD_YEAR    => 2;
use constant FIELD_MONTH   => 3;
use constant FIELD_LABEL   => 4;
use constant FIELD_ARTIST  => 5;
use constant FIELD_ALBUM   => 7;
use constant FIELD_UPC     => 8;
use constant FIELD_TRACK   => 9;
use constant FIELD_ISRC    => 10;
use constant FIELD_TYPE    => 11;
use constant FIELD_FORMAT  => 12;
use constant FIELD_UNITS   => 13;
use constant FIELD_PRICE   => 16;

#public methods

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

    my $lines = $args{lines};

    return undef unless ($lines);

    my %warnings = ();
    my $linenum  = 1;
    foreach my $line (@$lines) {
        if ( $linenum == 1 ) {
            ## skip header line
            $linenum++;
            next;
        }

        my $svcName = $line->[FIELD_SERVICE];
        $svcName =~ s/\s+-\s.+$//;
        my $serviceID = $self->getServiceID($svcName) || $service_map{$svcName};
        unless ($serviceID) {
            $self->warning();
            !$warnings{$svcName} && print STDERR "unknown service: $svcName ($line->[FIELD_SERVICE])\n";
            $warnings{$svcName} = 1;
            $linenum++;
            next;
        }

        my $countryCode = $ioda_countries{ $line->[FIELD_COUNTRY] };
        unless ($countryCode) {
            $self->warning();
            !$warnings{ $line->[FIELD_COUNTRY] } && print STDERR "unknown country: $line->[FIELD_COUNTRY]\n";
            $warnings{ $line->[FIELD_COUNTRY] } = 1;
            $linenum++;
            next;
        }

        my ( $dateBegin, $dateEnd ) = $self->_getDates( $line->[FIELD_YEAR], $line->[FIELD_MONTH] );
        my $artist = $line->[FIELD_ARTIST];
        my $album  = $line->[FIELD_ALBUM];
        my $track  = $line->[FIELD_TRACK];
        my $label  = $line->[FIELD_LABEL];
        my $upc    = $line->[FIELD_UPC];
        my $isrc   = $line->[FIELD_ISRC];

        my ($units)       = $line->[FIELD_UNITS] =~ m/^(\d+)$/;
        my ($total_price) = $line->[FIELD_PRICE] =~ m/^(\d+(\.\d+)?)$/;
        my $price = $total_price / $units if ( $total_price && $units && $units != 0 );

        my $type;
        if ( 't' eq lc $line->[FIELD_TYPE] ) {
            $type = RPS::File::Sale::TYPE_TRACK;
        } elsif ( 'a' eq lc $line->[FIELD_TYPE] ) {
            $type = RPS::File::Sale::TYPE_ALBUM;
        }

        my $format = $ioda_formats{ $line->[FIELD_FORMAT] };
        unless ($format) {
            $self->warning();
            !$warnings{ $line->[FIELD_FORMAT] } && print STDERR "unknown format: $line->[FIELD_FORMAT]\n";
            $warnings{ $line->[FIELD_FORMAT] } = 1;
            $linenum++;
            next;
        }

        if (   $serviceID
            && $units
            && ( $track || $album )
            && $artist
            && $dateBegin
            && $dateEnd
            && $countryCode
            && $format
            && $price
            && $type ) {
            my $sale = RPS::Import::SaleRec->new();

            $sale->serviceID($serviceID);
            $sale->productType($type);
            $sale->formatType($format);
            $sale->dateBegin($dateBegin);
            $sale->dateEnd($dateEnd);
            $sale->upc($upc);
            $sale->isrc($isrc);
            $sale->artistName($artist);
            $sale->albumName($album);
            $sale->trackName($track);
            $sale->labelName($label);
            $sale->units($units);
            $sale->price($price);
            $sale->lineNum($linenum);
            $sale->countryCode($countryCode);

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

    return $linenum;
}

#
# Private methods
#

sub _getDates {
    my $self  = shift;
    my $year  = shift;
    my $month = shift;

    my ( $dateBegin, $dateEnd );

    if ( $month =~ m/^q([1234])$/ ) {
        my $qtr = $1;
        if ( $qtr == 1 ) {
            $dateBegin = sprintf( "%04d-%02d-%02d", $year, 1, 1 );
            $dateEnd = sprintf( "%04d-%02d-%02d", $year, 3, Days_in_Month( $year, 3 ) );
        } elsif ( $qtr == 2 ) {
            $dateBegin = sprintf( "%04d-%02d-%02d", $year, 4, 1 );
            $dateEnd = sprintf( "%04d-%02d-%02d", $year, 6, Days_in_Month( $year, 6 ) );
        } elsif ( $qtr == 3 ) {
            $dateBegin = sprintf( "%04d-%02d-%02d", $year, 7, 1 );
            $dateEnd = sprintf( "%04d-%02d-%02d", $year, 9, Days_in_Month( $year, 9 ) );
        } else {
            $dateBegin = sprintf( "%04d-%02d-%02d", $year, 10, 1 );
            $dateEnd = sprintf( "%04d-%02d-%02d", $year, 12, Days_in_Month( $year, 12 ) );
        }
    } else {
        $month     = Decode_Month($month);
        $dateBegin = sprintf( "%04d-%02d-%02d", $year, $month, 1 );
        $dateEnd   = sprintf( "%04d-%02d-%02d", $year, $month, Days_in_Month( $year, $month ) );
    }

    return ( $dateBegin, $dateEnd );
}

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