package Distribution::Packager::CreateSpace;

use strict;
use POSIX qw(ceil);

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

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

my @md_fields = (

    #"contentID",  # blank??
    "label",             # label, truncate at 255 chars
    "artists",           # artist, truncate at 120 chars
    "composer",          # classical-only, truncate at 80 chars
    "name",              # title, truncate at 100 chars
                         #"description", # not needed, leave it out
    "search",            # genres, semi-colon separated
                         #"category", # their field, leave it out
                         #"release",  # their release date, leave it out
                         #"list",  # their list price, leave it out
    "mature",            # is Y/N
    "runtime",           # in minutes, rounded up to the next minute (less than 80)
                         # "shortDesc",  # not needed, leave it out
    "copyright",         # cline with "(c) " prefix
                         #"producer",  # optional
                         #"language",  # optional
    "externalSKU",       # our UPC/EAN
    "browseKeywords",    # genres from their xls doc
    "list",              # list price, TODO: figure this out
    "description",       # blah
    "release",           # release date: date we send or future date
    "category",          # use 'General'
    "amazonMP3only",
    "amazonMP3status",
    "explicitlyrics",
    "primarygenre",
    "primaryartist",
    "templateID",        # effectively vendor-id
    "printText0",        # TODO: holds 'artist', 'title', etc. for positioning on template
    "printText1",
    "printText2",
    "printText3",
    "printText4",
    "tracks",            # in ordered xml, 99 tx max: <track runtime="M:SS">title</track><track...
);

# directory structure:
# CODE_YYYYMMDDHHMMSS/
#     UPCUPCUPCUPC/
#         UPCUPCUPCUPC_DD_TTT.flac
#         UPCUPCUPCUPC.jpg
#         UPCUPCUPCUPC.xml
#     delivery.complete

sub build_package {
    my $self = shift;

    my $distDirName = $self->_get_dist_dir_name();
    my $baseDir     = $self->dist_dir($distDirName);
    $self->make_path($baseDir);
    my $imgDir = $baseDir . "/images";
    $self->make_path($imgDir);

    ## TODO: validate (at various stages) that album can be sent to CreateSpace, i.e.
    ##       not multi-disc, not compilation

    my @metadata;

  ALBUM: foreach my $album ( @{ $self->albums() } ) {
        my $upc = $album->{upc};
        my $albDir = join( '/', $baseDir, $upc );
        $self->make_path($albDir);

        my $imgDest = sprintf( "%s/%s.jpg", $imgDir, $upc );
        unless (
            $self->_convert_image(
                src  => $album->{'image-path-windows'},
                dest => $imgDest,
                xy   => 1448,
                dpi  => 300
            )
          ) {
            print STDERR "failed to convert image for $upc ($album->{'image-path-windows'})\n";
            $self->_cleanup_dir($albDir);
            next;
        }
        $album->{'image-filename'} = $upc . '.jpg';
        $album->{'image-checksum'} = $self->_get_file_checksum($imgDest);

        my %albumAttrs    = $album->getXMLParams();
        my $track_xml     = "";
        my $albumDuration = 0;

        ## TODO: count volumes; error if > 1;

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

            ## TODO: count tracks; error if > 99;

            foreach my $track ( @{ $volume->{track} } ) {
                my $trackSrc = $track->{'audio-path-windows'};
                my $trackSec = $self->_get_track_seconds($trackSrc);
                $albumDuration += $trackSec;
                my $trackDuration = sprintf( "%d:%02d", int( $trackSec / 60 ), $trackSec % 60 );

                my $trackNum = $track->{'sequence'};
                my $trackName = sprintf( "%s_%02d_%03d.flac", $upc, $volumeNum, $trackNum );
                unless ( File::Copy::copy( $trackSrc, "$albDir/$trackName" ) ) {
                    print STDERR "failed to copy $upc disc $volumeNum, track $trackNum: $!\n";
                    $self->_cleanup_dir($albDir);
                    next ALBUM;
                }
                $track->{'audio-filename'} = $trackName;
                $track->{'audio-checksum'} = $self->_get_file_checksum("$albDir/$trackName");

                $track_xml .= "<track runtime=\"$trackDuration\">" . $track->{'title'} . "</track>";
            }
        }

        $albumDuration = ceil( $albumDuration / 60 );

        if ( $albumDuration > 80 ) {    # or >= ?
            ## TODO: set as denied!
            next ALBUM;
        }

        my $album_metadata = join "\t", $album->{'label'}, $album->{'display-artist'}, "",    # TODO: composer
          $album->{'title'},
          $album->{'genre'},
          ( $albumAttrs{'is-explicit'} eq "explicit" ) ? "Y" : "N",
          $albumDuration,
          "(c) " . $album->{'cline'},
          $album->{'upc'}, "Alternative Rock",    #$self->_get_service_genre(genre_id => $album->{'genre-id'}), ## TODO: get it for real
          "999",                                  # TODO: figure this one out
          " ", $album->{'release-date'},          # tweak it any?
          "General",
          "N", "NOT_REQUESTED", ( $albumAttrs{'is-explicit'} eq "explicit" ) ? "Y" : "N", "Alternative Rock",    # TODO: get amazon genre
          $album->{'display-artist'}, $self->{AcctInfo}{code}, "",                                               # TODO: printtext0
          "",                                                                                                    # printtext1
          "",                                                                                                    # printtext2
          "",                                                                                                    # printtext3
          "",                                                                                                    # printtext4
          $track_xml;

        # album is complete so add it to success list & add metadata to tsv
        push @metadata, $album_metadata;
        $self->_complete_albums($album);
    }

    unshift @metadata, join( "\t", @md_fields );
    my $metadata_file = join( "/", $baseDir, "metadata.txt" );
    open METADATA, ">$metadata_file" or die "can't open $metadata_file for writing: $!";
    print METADATA join "\n", @metadata;
    close METADATA or warn "can't close $metadata_file: $!";
    return 1;
}

sub deliver_package {
    my $self = shift;

    # send the big blob
    my $retval = $self->SUPER::deliver_package();

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

    # TODO: send the confirmation file?

    return 1;
}

# part of amazon's dir name spec calls for using the minute so we need to
# check if the same name exists already # if so, then increment the minute
sub _get_dist_dir_name {
    my $self = shift;
    return $self->{DistDirName} if $self->{DistDirName};

    my ( $sec, $min, $hour, $mday, $mon, $year ) = localtime( $self->{Timestamp} );

    return sprintf( '%s_%d%02d%02d%02d%02d%02d', $self->{AcctInfo}{code}, $year + 1900, $mon + 1, $mday, $hour, $min, $sec );
}

1;
