package Distribution::Service::iTunes;

use strict;

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

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

# directory structure:
# whatever/
#     UPCUPCUPCUPC.itmsp/
#         UPCUPCUPCUPC_TT.jpg
#         UPCUPCUPCUPC_cover.jpg
#         metadata.xml

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);

    my @service_countries = qw(US CA JP AU NZ 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;
        }

        $self->_force_countries_allowed($album);

        ## set up directories
        my $upc = $album->{upc};
        my $dir = $baseDir . "/" . $upc . ".itmsp";
        $self->make_path($dir);

        my $orig_art = $self->_windoze_path( $album->{'image-path-full'} );
        my $conv_art = $upc . "_cover.jpg";
        unless ( $self->_convert_image( src => $orig_art, dest => $dir . "/" . $conv_art, xy => 600, dpi => 200 ) ) {
            print STDERR "image conversion failed on $upc";
            $self->_cleanup_dir($dir);
            next ALBUM;
        }
        $album->{'image-filename'} = $conv_art;
        $album->{'image-checksum'} = $self->_get_file_checksum( $dir . "/" . $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 $conv_audio = sprintf( "%s_%02d_%03d.flac", $upc, $vol_num, $track_num );
                unless ( File::Copy::copy( $orig_audio, "$dir/$conv_audio" ) ) {
                    print STDERR "audio conversion failed on $upc, disc $vol_num, track $track_num";
                    $self->_cleanup_dir($dir);
                    next ALBUM;
                }
                $track->{'audio-filename'} = $conv_audio;
                $track->{'audio-checksum'} = $self->_get_file_checksum("$dir/$conv_audio");
            }

            $volume->{'total-length'} = $self->_seconds_to_iso8601($volume_seconds);
        }
        my $metadata_file = $dir . "/metadata.xml";
        unless (
            $self->_translate_metadata(
                xmlSrc  => Common::WriteXML::GetXMLString( $album, "album", skip_array_indexing => 1 ),
                xmlDest => $metadata_file
            )
          ) {
            print STDERR "metadata conversion failed on $upc";
            $self->_cleanup_dir($dir);
            next ALBUM;
        }
        $self->_complete_albums($album);
    }

    return 1;
}

sub deliver_package {
    my $self     = shift;
    my $delivery = Distribution::Delivery::ITMS->new(
        base_path    => $self->{TempDir},
        package_path => $self->{DistDirName},
        account_name => $self->{AcctInfo}{code}
    );
    ## TODO: return value of deliver() ?
    $delivery->deliver();
    return 1;
}

sub _get_dist_dir_name {
    my $self = shift;
    my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime( $self->{Timestamp} );
    return sprintf( '%d%02d%02d%02d%02d%02d_%s', $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $$ );
}

sub _convert_audio {
    my $self = shift;
    my $src  = shift;
    my $dst  = shift;
    return File::Copy::copy( $src, $dst );
}

1;
