# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id
#------------------------------------------------------------
package MediaServe::Audio::AudioFile;
use strict;
use warnings;

use lib '/app/tools/common/lib';
use Common::Assert;
use Common::Log;
use RSApache::DBSession;

use lib '/app/tools/mediaserve/lib';
use MediaServe::File;
use MediaServe::DB::Item::MediaFile;

use base 'MediaServe::File';

use constant kDefaultTimeToLive => 300;    # 5 minutes

# ----> How to use this class <----
#
# To generate a temporary URL to an image file, do this:
#
# my $audioFileObj = MediaServe::Audio::AudioFile->new
# (
#   clientID => Common::RSApp::GetClientID(),
#   id => $audioFileID,
# );
#
# my $url = $audioFile->url
# (
#   sessionID => RSApache::DBSession::GetSessionIDFromCookie,
#   expirationDate => time() + $secondsToLive,
# );
#

sub _deriveToken {
    my ($self) = @_;

    # We will need the ID and the expiration date, or this won't work.
    #
    assert( defined $self->clientID() );
    assert( defined $self->id() );
    assert( defined $self->expirationDate() );

    # !!! We will also need the storageHostID and datarootID.
    # !!! These come from the media_file table.
    my $mediaFileObj = MediaServe::DB::Item::MediaFile->Lookup( media_file_id => $self->id() );
    die "ERROR - invalid media_file_id " . $self->id() unless $mediaFileObj;
    my $storageHostID = $mediaFileObj->storage_host_id;
    my $datarootID    = $mediaFileObj->dataroot_id;

    # So, they want a fancy filename, eh?
    #[artist_name]_[album_title]_[.CD.disc_no]_[track_no].mp3t
    # sigh - this means that I will have to look up all sorts of crap.
    #
    # product_track_file => product_track => ...

    # We're going to want to pass regular ole' bytes to the encryption routine.
    # So, I want to make sure that 'id' and 'expire' are strings, then pack them
    # into a byte buffer.  Hence the (perhaps unnecessary) sprintf.
    #

    my $clientID = sprintf( "%lu", $self->clientID() );
    my $id       = sprintf( "%lu", $self->id );
    my $expire   = sprintf( "%lu", $self->expirationDate );
    my $sessionID = sprintf( "%lu", ( $self->sessionID ? $self->sessionID : 0 ) );

    my $unencryptedToken = pack( "LLLLLL", $clientID, $id, $sessionID, $storageHostID, $datarootID, $expire );

    # Token will be a string containing hex digits
    #
    $self->{Token} = MediaServe::File->Encrypt($unencryptedToken);
}

sub _deriveID {
    my ($self) = @_;

    # Extract this from the token.
    # Get the expiration date while we're at it.
    #
    my $token = $self->token();
    assert( defined $token );

    my $decrypted = MediaServe::File->Decrypt($token);
    my ( $clientID, $id, $sessionID, $storageHostID, $datarootID, $date ) = unpack( "LLLLLL", $decrypted );
    $self->{ClientID}       = $clientID;
    $self->{ID}             = $id;
    $self->{ExpirationDate} = $date;
    $self->{SessionID}      = $sessionID;
    $self->{StorageHostID}  = $storageHostID;
    $self->{DatarootID}     = $datarootID;
}

sub _deriveExpirationDate {
    my ($self) = @_;

    if ( defined $self->{Token} ) {

        # We'll do everything in _deriveID...
        #
        $self->_deriveID();
    } else {

        #        $self->{ExpirationDate} = time() + kDefaultTimeToLive;
        # We really don't care about expiration time for audio files.
        #
        $self->{ExpirationDate} = 0;
    }
}

sub _deriveSessionID {
    my ($self) = @_;

    if ( defined $self->{Token} ) {

        # We'll do everything in _deriveID...
        #
        $self->_deriveID();
    } else {
        $self->{SessionID} = RSApache::DBSession::GetSessionIDFromCookie();
    }
}

sub _deriveClientID {
    my ($self) = @_;

    # We'll do everything in _deriveID...
    #
    $self->_deriveID();
}

sub _deriveStorageHostID {
    my ($self) = @_;
    $self->_deriveID();
}

sub _deriveDatarootID {
    my ($self) = @_;
    $self->_deriveID();
}

sub _deriveFileName {
    my ($self) = @_;

    # The filename is just the id.
    #
    $self->{FileName} = $self->id();
}

sub fileType {
    my ($self) = @_;

    return 'audio/mpeg';
}

sub mediaType {
    return 'audio';
}

sub url {
    my ($self) = @_;

    my $url;

    my $mediaFileObj = MediaServe::DB::Item::MediaFile->Lookup( media_file_id => $self->id() );
    if ( !$mediaFileObj ) {
        Common::Log::Print( "MediaServe ERROR - invalid media_file_id " . $self->id() );
        return undef;
    }

    if ( 'active' eq $mediaFileObj->status ) {
        $url = '/media/' . $self->mediaType() . '/show/' . $self->token();
    }

    return $url;
}

1;
