#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package MediaServe::Image::ImageFile;
use strict;
use warnings;

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

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

use base 'MediaServe::File';

use constant kProcessingImagePath => '/production/images/image_processing.png';
use constant kDefaultTimeToLive   => 300;

# ----> How to use this class <----
#
# To generate a temporary URL to an image file, do this:
#
# my $imageFileObj = MediaServe::Image::ImageFile->new
# (
#   clientID => Common::RSApp::GetClientID(),
#   id => $imageFileID,
# );
#
# my $url = $imageFile->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;

    # 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;
    }
}

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 id and the filename are the same.
    #
    $self->{FileName} = $self->id();
}

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

    return 'image/jpeg';
}

sub mediaType {
    return 'img';
}

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

    my $url;

    # If the file is not marked as available, we'll use a placeholder image.
    #
    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 = 'http://media.royaltyshare.com/media/' . $self->mediaType() . '/' . $self->token();
        $url = '/media/' . $self->mediaType() . '/show/' . $self->token();
    } else {
        $url = kProcessingImagePath;
    }

    Log->debug("MediaServe::Image::ImageFile::url called, returning url $url");
    return $url;
}

1;
