use strict;
use Data::Dumper;
use Getopt::Std;
use Sys::CpuLoad;
use Win32::Daemon;
use Proc::Background;
use FileHandle;

use lib 'd:/app/tools/appuser/lib';
use lib 'd:/app/tools/common/lib';
use lib 'd:/app/tools/data_classes/lib';
use lib 'd:/app/tools/distribution/lib';
use lib 'd:/app/tools/job/lib';
use lib 'd:/app/tools/mediaserve/lib';
use lib 'd:/app/tools/metadata/lib';
use lib 'd:/app/tools/rps/lib';
use lib 'd:/app/tools/sysadmin/lib';

use Common::RSApp;
use Common::Log;

use Job::Queue;
use Job::Job;
use Job::Scheduler::Windows;
use Job::Config;
use Job::JobRuleSet;
use Job::DB::Item::JobHost;

my $gVerbosityLevel = 5;

my $gAppSingleton;

# Parse the command-line options.
#
my %options;
_parseCommandLine( \%options );

# Open the config file
#
my $gConfig = Job::Config->new();

my $gPidFilePath = $gConfig->get('scheduler_pid_file_path');
my $gLogFilePath = $gConfig->get('scheduler_log_file_path');
my $sleepTime    = $gConfig->get('scheduler_sleep_time');

# We'll fill this in once we have a singleton
#
my $gHostname;

# Instantiate the Scheduler object.
#
my $gScheduler = Job::Scheduler::Windows->new(%options);

# Read the sleep time from the config file
#
my $config = Job::Config->new();

# Start the service.
Win32::Daemon::StartService();

open STDOUT, '>>' . $gLogFilePath or die "CANNOT OPEN $gLogFilePath : $!";
open STDERR, '>>' . $gLogFilePath or die "CANNOT OPEN $gLogFilePath : $!";
STDOUT->autoflush(1);
STDERR->autoflush(1);

$gAppSingleton = Common::RSApp->new( clientID => 0 );

$gHostname = Common::RSApp::GetHostname();

####
#    Main Event Loop
####
my ( $State, $LastState );

while ( SERVICE_STOPPED != ( $State = Win32::Daemon::State() ) ) {
    if ( SERVICE_START_PENDING == $State ) {

        # Initialization code
        $LastState = SERVICE_RUNNING;
        Win32::Daemon::State(SERVICE_RUNNING);
        report("Service initialized. Setting state to Running.");
    } elsif ( SERVICE_PAUSE_PENDING == $State ) {
        $LastState = SERVICE_PAUSED;
        Win32::Daemon::State(SERVICE_PAUSED);
        report("Pausing.");
        next;
    } elsif ( SERVICE_CONTINUE_PENDING == $State ) {
        $LastState = SERVICE_RUNNING;
        Win32::Daemon::State(SERVICE_RUNNING);
        report("Resuming from paused state.");
        next;
    } elsif ( SERVICE_STOP_PENDING == $State ) {
        $LastState = SERVICE_STOPPED;
        Win32::Daemon::State( [ state => SERVICE_STOPPED, error => 1234 ] );
        report("Stopping service.");
        next;
    } elsif ( SERVICE_RUNNING == $State ) {
        report( "Service running.", 3 );
        $gScheduler->run($gHostname);
    } else {

        # Take care of unhandled states by setting the State()
        # to whatever the last state was we set...
        Win32::Daemon::State($LastState);
        report("Unknown service state ($State). ");
    }

    Win32::Sleep( $sleepTime * 1000 );
}

print Win32::Daemon::StopService();

sub _usage {
    print STDERR "\nusage: $0 [-s <sleep time> -c <conf_file_path>] [-V <verbosity>]\n";
    print STDERR "\n";
    print STDERR "Arguments:\n";
    print STDERR "\t-s <sleep time>\t\tTime (in seconds) to sleep between queries of the job queue.\n";
    print STDERR "\t-c <conf_file_path>\t\tPath to the configuration file.\n\t\t Defaults to /app/tools/job/conf/job_scheduler.conf\n";
    print STDERR "\t-V <verbosity>\t\tSet the verbosity level - higher numbers mean more messages\n";
}

sub _parseCommandLine {
    my ($settings) = @_;

    my %opt;
    getopts( 'V:c:s:', \%opt );

    if ( $opt{V} ) {
        $gVerbosityLevel = $opt{V};
    }
}

sub report {
    my ( $msg, $level ) = @_;
    $level = 1 unless $level;

    if ( $level <= $gVerbosityLevel ) {
        Common::Log::Print($msg);
    }
}

sub debug {
    my ($msg) = @_;

    open DEBUG, '>> C:\app\data\logs\WRAPPER_DEBUG.txt' or die "cannot open debug log file";
    print DEBUG localtime() . " $msg\n";
    close DEBUG;
}
