package Distribution::Service::Napster;

use strict;

use lib '/app/tools/distribution/lib';
use base 'Distribution::Manager';

use constant TRANSFORM => 'napster-transform.xsl';

my %AUDIO_CONFIG = (
    1 => {
        file_ext => 'wma',
        bit_rate => 20,
        freq     => 22,
        signal   => 'mono',
    },
    2 => {
        file_ext => 'wma',
        bit_rate => 32,
        freq     => 32,
        signal   => 'stereo',
    },
    7 => {
        file_ext => 'wma',
        bit_rate => 128,
        freq     => 44,
        signal   => 'stereo',
    },
    8 => {
        file_ext => 'wma',
        bit_rate => 192,
        freq     => 44,
        signal   => 'stereo',
    },
    12 => {
        file_ext => 'mp3',
        bit_rate => 256,
    },
);

# directory structure:
# COD????????/
#     audio/
#         wma/
#             CODE_UPC_DD_TTT_001.wma
#             CODE_UPC_DD_TTT_002.wma
#             CODE_UPC_DD_TTT_007.wma
#             CODE_UPC_DD_TTT_008.wma
#         mp3/
#             CODE_UPC_DD_TTT_012.mp3
#     graphics/
#         CODE_UPC_001.jpg
#     xml/
# COD????????.complete

sub build_package {
    my $self = shift;

    ## create delivery directory structure
    $self->{DistDirName} = $self->_get_dist_dir_name();
    my $baseDir = $self->dist_dir( $self->{DistDirName} );
    $self->{PackageDir} = $baseDir;
    $self->make_path($baseDir);
    $self->make_path( $baseDir . "/audio/wma" );
    $self->make_path( $baseDir . "/audio/mp3" );
    $self->make_path( $baseDir . "/graphics" );
    $self->make_path( $baseDir . "/xml" );

    my $success_xml = '';

    my @service_countries = qw(US CA JP GB BE BG CZ DK DE EE IE EL ES FR IT CY
      LV LT LU HU MT NL AT PL PT RO SI SK FI SE);

  ALBUM: foreach my $album ( @{ $self->albums() } ) {
        unless ( $self->_can_be_sold_in( $album, \@service_countries ) ) {
            $self->_album_denied( $album, $self->{TerritoriesDeniedMsg} );
            next ALBUM;
        }

        ## set up directories
        my $upc = $album->{upc};
        my $dir = $self->{PackageDir};

        my $orig_art    = $self->_windoze_path( $album->{'image-path-full'} );
        my $file_prefix = $self->{AcctInfo}{code} . "_" . $upc;
        my $conv_art    = $file_prefix . "_001.jpg";
        unless ( $self->_convert_image( src => $orig_art, dest => $dir . "/graphics/" . $conv_art, xy => 1080, dpi => 72 ) ) {
            print STDERR "image conversion failed on $upc";
            $self->_cleanup_content( $self->{AcctInfo}{code} . "_" . $upc );
            next ALBUM;
        }
        $album->{'album-filename-prefix'} = $file_prefix;
        $album->{'image-filename'}        = $conv_art;
        $album->{'image-checksum'}        = $self->_get_file_checksum( $dir . "/graphics/" . $conv_art );

        foreach my $volume ( @{ $album->{volume} } ) {
            my %volAttrs       = $volume->getXMLParams();
            my $vol_num        = $volAttrs{id};
            my $volume_seconds = 0;

            foreach my $track ( @{ $volume->{track} } ) {
                my $track_num  = $track->{'sequence'};
                my $orig_audio = $self->_windoze_path( $track->{'audio-path-full'} );

                my $track_seconds = $self->_get_track_seconds($orig_audio);
                $track->{'length'} = $self->_seconds_to_iso8601($track_seconds);
                $volume_seconds += $track_seconds;

                my $file_prefix = sprintf( "%s_%s_%02d_%03d", $self->{AcctInfo}{code}, $upc, $vol_num, $track_num );
                $track->{'track-filename-prefix'} = $file_prefix;

                foreach my $fileID ( sort keys %AUDIO_CONFIG ) {
                    my $conv_audio = sprintf(
                        "%s_%s_%02d_%03d_%03d.%s",
                        $self->{AcctInfo}{code},
                        $upc, $vol_num, $track_num, $fileID, $AUDIO_CONFIG{$fileID}{file_ext}
                    );
                    my $conv_path = join( '/', $dir, 'audio', $AUDIO_CONFIG{$fileID}{file_ext}, $conv_audio );

                    unless ( $self->_convert_audio( $fileID, $orig_audio, $conv_path ) ) {
                        print STDERR "audio conversion failed on $upc, disc $vol_num, track $track_num\n";
                        $self->_cleanup_content( $self->{AcctInfo}{code} . '_' . $upc );
                        next ALBUM;
                    }
                    $track->{ 'audio-filename-' . $fileID } = $conv_audio;
                    $track->{ 'audio-checksum-' . $fileID } = $self->_get_file_checksum($conv_path);
                }
            }
            $volume->{'total-length'} = $self->_seconds_to_iso8601($volume_seconds);
        }
        $success_xml .= Common::WriteXML::GetXMLString( $album, 'album', skip_array_indexing => 1, skip_definition => 1 );
        $self->_complete_albums($album);
    }

    my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime( $self->{Timestamp} );
    $success_xml =
        "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
      . "<catalog>"
      . "<shipment-date>"
      . sprintf( "%d%02d%02d", $year + 1900, $mon + 1, $mday )
      . "</shipment-date>"
      . "<shipment-name>"
      . $self->{DistDirName}
      . "</shipment-name>"
      . "<distributor-name>"
      . $self->{AcctInfo}{code}
      . "</distributor-name>"
      . $success_xml
      . "</catalog>";

    my $metadata_file = $baseDir . "/xml/" . $self->{DistDirName} . ".xml";
    unless ( $self->_translate_metadata( xmlSrc => $success_xml, xmlDest => $metadata_file ) ) {
        print STDERR "metadata conversion failed\n";
        return 0;
    }

    return 1;
}

sub deliver_package {
    my $self = shift;

    my $retval = $self->SUPER::deliver_package();

    return $retval if ( $retval == 0 );

    my $complete_file = join( '/', $self->{TempDir}, $self->{DistDirName} . '.complete' );
    open( F, '>', $complete_file ) or die "can't open $complete_file: $!";
    close(F) or warn "can't close $complete_file: $!";

    return $self->SUPER::deliver_package( src => $self->{DistDirName} . '.complete', dont_retry => 1 );
}

sub _get_dist_dir_name {
    my $self = shift;
    return sprintf( '%s%0x', $self->{AcctInfo}{code}, uc $self->{Timestamp} );
}

sub _convert_audio {
    my $self = shift;
    my $type = shift;

    unless ( $AUDIO_CONFIG{$type} ) {
        print STDERR "unknown type: $type\n";
        return 0;
    }

    my %args = %{ $AUDIO_CONFIG{$type} };
    $args{src}  = shift;
    $args{dest} = shift;
    my $fileType = delete $args{file_ext};

    if ( $fileType eq 'wma' ) {
        return $self->_flac_to_wma(%args);
    }

    # else - mp3
    return $self->_flac_to_mp3(%args);
}

sub _cleanup_content {
    my $self   = shift;
    my $prefix = shift;
    my $path   = $self->{PackageDir} . "/audio/wma/" . $prefix;
    unlink <$path*> or die "can't clean ${path}*: $!";
    $path = $self->{PackageDir} . "/audio/mp3/" . $prefix;
    unlink <$path*> or die "can't clean ${path}*: $!";
    $path = $self->{PackageDir} . "/graphics/" . $prefix;
    unlink <$path*> or die "can't clean ${path}*: $!";
    return 1;
}

1;
