#!/usr/bin/perl

# $Id: dvdrip-master,v 1.1 2005/10/09 11:27:25 joern Exp $

#-----------------------------------------------------------------------
# Copyright (C) 2001-2003 Jrn Reder <joern@zyn.de> All Rights Reserved
# 
# This program is part of Video::DVDRip, which is free software; you can
# redistribute it and/or modify it under the same terms as Perl itself.
#-----------------------------------------------------------------------

package Video::DVDRip;

use strict;
use lib 'lib';
use Getopt::Std;

#-- l10n stuff
use POSIX qw(setlocale);
use Locale::Messages qw (LC_MESSAGES);
use Locale::TextDomain ("video.dvdrip");
setlocale(LC_MESSAGES,"");

BEGIN {
	# That's Perl! The job classes inherit from this class,
	# which is decided at *runtime* - this way standard and
	# cluster mode can share the same job execution system
	# by inserting the cluster logic dynamically into the
	# inheritence line... great stuff!
	$Video::DVDRip::JobClass = "Video::DVDRip::Cluster::Job";

	my @missing_modules;
	foreach my $module ( qw ( Event Storable Event::RPC ) ) {
		eval "use $module";
		push @missing_modules, $module if $@;
	}
	if ( @missing_modules ) {
		print "\nThe following Perl modules are needed for the cluster mode:\n\n";
		print "    ".join(", ",@missing_modules),"\n\n";
		print "Please read the documentation at:\n\n";
		print "    http://www.exit1.org/dvdrip/doc/install.cipp#cluster\n";
		print "    http://www.exit1.org/dvdrip/doc/cluster.cipp\n\n";
		exit 1;
	}

	$Video::DVDRip::PREFERENCE_FILE = "$ENV{HOME}/.dvdriprc";
}

use Video::DVDRip;

use Event::RPC 0.84;
use Event::RPC::Server;
use Event::RPC::Logger;

my $USAGE = <<__EOU;
Usage: dvdrip-master [-w [-W port] ] [loglevel]

       loglevel  logs messages to stdout
                 1 - basic logging, no details
		 2 - log actual jobs
		 3 - log all executed commands also

       -w        start webserver service
       -W port   port for webserver (default: 8888)

__EOU

main: {
	# get options
	my %opt;
	my $opt_ok = getopts ('W:w', \%opt);
	my $log_level = shift @ARGV || 0;

	print ($USAGE), exit 1 if not $opt_ok or @ARGV;

	my $start_webserver = $opt{w};
	my $webserver_port  = $opt{W} || 8888;

	my $logger = Event::RPC::Logger->new (
	    fh_lref => [ \*STDOUT ],
	);
	$logger->set_min_level($log_level);

	# setup master RPC Server with class interface declaration
	my $server = Event::RPC::Server->new (
		name    => "dvd::rip cluster control daemon",
		port    => 28646,
		logger  => $logger,
		start_log_listener => 1,
		classes => {
			'Video::DVDRip::Cluster::Master' => {
				get_master		=> '_constructor',
				hello			=> 1,
				save            	=> 1,
				add_project		=> 1,
				add_node		=> 1,
				move_up_project 	=> 1,
				move_down_project	=> 1,
				remove_node		=> 1,
				schedule_project	=> 1,
				remove_project		=> 1,
				shutdown		=> 1,
				projects_list		=> 1,
				nodes_list		=> 1,
				projects		=> '_object',
				nodes			=> '_object',
				get_node_by_name	=> '_object',
				get_project_by_id	=> '_object',
				node_test		=> 1,
				get_master_node		=> '_object',
			},

			'Video::DVDRip::Cluster::Project' => {
				new			=> '_constructor',
				id			=> 1,
				name			=> 1,
				label			=> 1,
				state			=> 1,
				progress		=> 1,
				create_job_plan		=> 1,
				title			=> '_object',
				reset_job		=> 1,
				jobs_list		=> 1,
				get_job_by_id		=> 1,
				save			=> 1,
			},


			'Video::DVDRip::Cluster::Node' => {
				new			=> '_constructor',
				save			=> 1,
				name			=> 1,
				hostname		=> 1,
				data_base_dir		=> 1,
				is_master		=> 1,
				data_is_local		=> 1,
				username		=> 1,
				ssh_cmd			=> 1,
				state			=> 1,
				job_info		=> 1,
				progress		=> 1,
				project_name		=> 1,
				tc_options		=> 1,
				set_name		=> 1,
				set_hostname		=> 1,
				set_data_base_dir	=> 1,
				set_is_master		=> 1,
				set_data_is_local	=> 1,
				set_username		=> 1,
				set_ssh_cmd		=> 1,
				set_tc_options		=> 1,
				stop			=> 1,
				start			=> 1,
				run_tests		=> 1,
				get_test_command	=> 1,
				parse_test_output	=> 1,
				test_finished		=> 1,
				test_result		=> 1,
				clone			=> '_object',
			},
			'Video::DVDRip::Cluster::Title' => {
				project			=> '_object',
				program_stream_units    => '_object',
				save			=> 1,
				calc_chunk_cnt		=> 1,
				chunk_cnt_sum		=> 1,
				with_avisplit		=> 1,
				set_with_avisplit	=> 1,
				with_cleanup		=> 1,
				set_with_cleanup	=> 1,
				with_vob_remove		=> 1,
				set_with_vob_remove	=> 1,
				frames_per_chunk	=> 1,
				set_frames_per_chunk	=> 1,
				info			=> 1,
			},
			'Video::DVDRip::Cluster::PSU' => {
				nr			=> 1,
				frames			=> 1,
				selected		=> 1,
				set_selected		=> 1,
			},
		},
	);

	$Video::DVDRip::DEBUG = 2 if $log_level > 3;

	# start master
	$server->load_class("Video::DVDRip::Cluster::Master");

	Video::DVDRip::Cluster::Master->check_prerequisites;

	my $master = Video::DVDRip::Cluster::Master->new (
		logger     => $logger,
		rpc_server => $server,
	);
	$master->job_control;

	if ( $start_webserver ) {
		# start webserver
		require Video::DVDRip::Cluster::Webserver;
		my $webserver = Video::DVDRip::Cluster::Webserver->new (
			port   => $webserver_port,
			master => $master->get_master,
		);
	}

	# start the object RPC server
	$server->start;
}

