#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package MediaServe::Server;

use strict;
use Data::Dumper;

use lib '/app/tools/mediaserve/lib';
use MediaServe::Image::ImageFile;
use MediaServe::Audio::AudioFile;
use MediaServe::DB::Item::MediaFile;

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

# GetNewMediaFile
#
# my $mediaFileObj = MediaServe::Server::GetNewMediaFile($filename);
#
# Returns a _new_ MediaServe::DB::Item::MediaFile object.
# This method will abstract away the dataroot and storage_host setup process.
# In most cases you will want to use this method, rather than calling
# MediaServe::DB::Item::MediaFile->Create() directly.
#
sub GetNewMediaFile {
    my ($filename) = @_;

    assert($filename);

    # !!! For now this will really be nothing more that a wrapper around Create().
    # !!! We'll get fancy with dataroot and storage_host allocation later...
    #
    my $obj = MediaServe::DB::Item::MediaFile->Create();
    $obj->filename($filename);
    $obj->dataroot_id( MediaServe::MediaFile->_writeDataroot() );
    $obj->save();

    return $obj;
}

# GetImagePath
#
# my ($hostname, $absolutePath) = MediaServe::Server::GetImagePath(clientID => $clientID, mediaFileID => $mediaFileID, type = {windows|linux} );
#
# Returns the hostname and absolute path on that host where an image file belongs.
# This does not imply that the file is actually _there_ - Just that this is where it ought to be.
#
sub GetImagePath {
    my (%args) = @_;

    my $mediaFileID = $args{mediaFileID};
    my $clientID    = $args{clientID};

    assert($mediaFileID);
    assert($clientID);

    my $imageFileObj = MediaServe::Image::ImageFile->new( id => $mediaFileID, clientID => $clientID, type => $args{type} );
    my $hostname = $imageFileObj->hostname();

    # The 'relative path' is something like 'img/14/000/000/004/123/4123'
    # We will need the absolute path, which ought to include the base path.
    #
    my $path = $imageFileObj->logicalVolume() . '/' . $imageFileObj->relativePath() . '/' . $imageFileObj->filename();
    Common::Log::Debug("MediaServe::Server::GetImagePath called with mediaFileID $mediaFileID clientID $clientID, returning path $path");

    return ( $hostname, $path );
}

# GetAudioPath
#
# my ($hostname, $absolutePath) = MediaServe::Server::GetAudioPath(clientID => $clientID, mediaFileID => $mediaFileID);
#
# Returns the hostname and absolute path on that host where an audio file belongs.
# This does not imply that the file is actually _there_ - Just that this is where it ought to be.
#
sub GetAudioPath {
    my (%args) = @_;

    my $mediaFileID = $args{mediaFileID};
    my $clientID    = $args{clientID};
    my $type        = $args{type};

    assert($mediaFileID);
    assert($clientID);

    my $audioFileObj = MediaServe::Audio::AudioFile->new( id => $mediaFileID, clientID => $clientID, type => $type );
    my $hostname = $audioFileObj->hostname();

    # The 'relative path' is something like 'aud/14/000/000/004/123/4123'
    # We will need the absolute path, which ought to include the base path.
    #
    my $path = $audioFileObj->logicalVolume() . '/' . $audioFileObj->relativePath() . '/' . $audioFileObj->filename();
    Common::Log::Debug("MediaServe::Server::GetAudioPath called with mediaFileID $mediaFileID clientID $clientID, returning path $path");

    return ( $hostname, $path );
}

sub DeleteAudio {
    my (%args) = @_;

    my $mediaFileID = $args{mediaFileID};
    my $clientID    = $args{clientID};

    assert($mediaFileID);
    assert($clientID);

    my ( undef, $path ) = GetAudioPath( clientID => $clientID, mediaFileID => $mediaFileID );
    if ( -e $path ) {
        Common::Log::Debug("Unlink: $path");
        unlink($path);
    }

    my $trackDBObj = MediaServe::DB::Item::ProductTrackFile->Lookup( media_file_id => $mediaFileID );

    # If we know the album_id then lets clear the validation status.
    my $albumDBObj = RPS::DB::Item::Album->LookupByProductTrackID( product_track_id => $trackDBObj->product_track_id )
      if ( $trackDBObj && $trackDBObj->product_track_id );

    if ($albumDBObj) {
        my $cache = new RPS::Catalog::DistributionCache;
        $cache->clearAlbumStatus( albumID => $albumDBObj->album_id );
    }

    $trackDBObj->delete() if ($trackDBObj);

    _deleteMediaFile(@_);

}

sub DeleteImage {
    my (%args) = @_;

    my $mediaFileID = $args{mediaFileID};
    my $clientID    = $args{clientID};

    assert($mediaFileID);
    assert($clientID);

    my ( undef, $path ) = GetImagePath( clientID => $clientID, mediaFileID => $mediaFileID );
    if ( -e $path ) {
        Common::Log::Debug("Unlink: $path");
        unlink($path);
    }

    my $albumDBObj = MediaServe::DB::Item::AlbumFile->Lookup( media_file_id => $mediaFileID );

    # If we know the album_id then lets clear the validation status.
    if ( $albumDBObj && $albumDBObj->album_id ) {
        my $cache = new RPS::Catalog::DistributionCache;
        $cache->clearAlbumStatus( albumID => $albumDBObj->album_id );
    }

    $albumDBObj->delete() if ($albumDBObj);

    _deleteMediaFile(@_);
}

sub _deleteMediaFile {
    my (%args) = @_;

    my $mediaFileID = $args{mediaFileID};
    my $clientID    = $args{clientID};

    assert($mediaFileID);
    assert($clientID);

    Common::Log::Debug("Remove MediaFile DB Record (MediaFileID: $mediaFileID)");
    my $mfDBObj = MediaServe::DB::Item::MediaFile->Lookup( media_file_id => $mediaFileID );
    $mfDBObj->delete() if ($mfDBObj);
}

1;
