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

use strict;
use warnings;

use Sys::Hostname;

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

use lib '/app/tools/job/lib';
use Job::Job;
use Job::DB::Item::Job;

# Static method that returns the Queue object for the specified host - or the queue on the local host.
#
# ALWAYS use this to get a Queue - never call Job::Queue->new() directly. please.
#
sub GetQueue {
    my ($hostname) = @_;

    $hostname = hostname() unless $hostname;

    # to be consistent, we'll strip out any domain qualifiers from hostname.
    #
    ($hostname) = split( /\./, $hostname );

    # !!! Do we want to 'cache' these object references, or just create new ones?
    # !!! I don't currently see any compelling reason to cache... At least, not yet.
    #

    return Job::Queue->new( hostname => $hostname );
}

# This submits a job to a specific host's queue.
# I don't want to change this interface - but it is not appropriate
# for multi-host class based jobs.
#
sub submitJob {

    #    my ($self, $commandLine, $priority) = @_;
    my ( $self, %args ) = @_;

    assert( $args{commandLine}, 'commandLine is required' );

    $args{priority} = Job::Job::kPriorityNormal unless defined $args{priority};

    # First, create an entry in the database - This queues the job.
    # Then create a Job abstraction around that information
    #
    my $dbItem = Job::DB::Item::Job->Create(
        command_line => $commandLine,
        hostname     => $self->getHostname(),
        priority     => $priority,
        status       => Job::Job::kStatusQueued,
    );

    if ( $args{class} ) {
        $dbItem->class( $args{class} );
    }

    $dbItem->save();

    my $job = Job::Job->new( _dbItem => $dbItem );
    return $job;

}

sub getJob {
    my ( $self, $jobID ) = @_;
    assert($jobID);

    return Job::Job->new( jobID => $jobID );
}

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

    my $dbItem = Job::DB::Item::Job::GetHighestPriorityQueuedJob( $self->{Hostname} );
    return undef unless $dbItem;
    return Job::Job->new( _dbItem => $dbItem );
}

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

    return Job::DB::Item::Job::GetNumberOfJobsRunning( $self->{Hostname} );
}

sub getHostname {
    my ($self) = @_;
    return $self->{Hostname};
}

sub _init {
    my ( $self, %args ) = @_;
    $self->SUPER::_init(%args);

    assert( $args{hostname} );
    $self->{Hostname} = $args{hostname};

    return $self;
}

1;
