#!/usr/bin/perl
use warnings;
use strict;

use Getopt::Long;
use Elive::Util;
use Elive::Entity;
use DateTime::Format::ISO8601;
use Pod::Usage;

use Carp;

my $username = 'serversupport';
my $password;
;
my $debug;
my $facilitator;
my $start_str;
my $end_str;
my $meeting_name = 'elive test meeting';
my $meeting_password;
my $max_talkers;
my $raise_hands;
my $preload;
my $url;
my $help;

use Carp;

=head1 NAME

elive_raise_meeting

=head1 SYNOPSIS

elive_raise_meeting   http://myserver.com/my-site[:port] userid[=role] [userid[=role]...]

    -user someuser              # server login user
    -pass somepass              # server login password

    -facilitator userId
    -name 'my meeting name'
    -meeting_pass otherpass     # meeting password
    -preload file               # local file to upload as a preload
    -start  'YYYY-MM-DD HH:MM'  # start time
    -end '[YYYY-MM-DD] HH::MM'  # end time
    -max_talkers                # max no. of simultaneous talkers
    -help

=head1 DESCRIPTION

Creates a meeting on an Elluminate Live (c) server

=head1 SEE ALSO

    perldoc Elive
    http://search.cpan/org?Elive

=cut

GetOptions(
    'name|meeting_name=s' => \$meeting_name,
    'username|user=s' => \$username,
    'password|pass=s' => \$password,
    'facilitator|moderator=s' => \$facilitator,
    'start=s' => \$start_str,
    'end=s' => \$end_str,
    'meeting_password|meeting_pass=s' => \$meeting_password,
    'max_talkers=i' => \$max_talkers,
    'raise_hands' => \$raise_hands,
##	   'private' => \$private,
    'debug=i' => \$debug,
    'help|?' => \$help,
    )
    && (($help && pod2usage(2)) || ($url = shift @ARGV))
    or die pod2usage(1);

Elive->debug($debug);

if ($debug) {
    $SIG{__WARN__} = \&Carp::cluck;
    $SIG{__DIE__} = \&Carp::confess;
}

our $connection = Elive->connect(
    $url      ||= Elive::Util::prompt('Elluminate Server: '),
    $username ||= Elive::Util::prompt('Username: '),
    $password ||= Elive::Util::prompt('Password: '),
    );

do {

    my $start = $start_str
	? DateTime::Format::ISO8601->parse_datetime($start_str)
	: DateTime->now->clone->add(minutes => 15);

    my $end = $end_str
	? DateTime::Format::ISO8601->parse_datetime($end_str,
						    base_datetime => $start)
	: $start->clone->add(minutes => 30);

    die "end time must be later than start time"
	unless ($end->epoch > $start->epoch);

    my $facilitator_obj = $facilitator
	? _get_user($facilitator)
	: Elive->_login;

    my @participants;

    foreach my $spec (@ARGV) {

	#
	# parse a participant spec: user[=roleId]
	#
	my $user_spec;
	my $role;

	if (($user_spec,$role) = ($spec =~ m{^([^=]+)=([^=]+)$}x)) {
	    die "non-numeric role: $spec"
		unless $role =~ m{^\d+$};
	}
	else {
	    $user_spec = $spec;
	}

	$role = 3 if (!defined $role);

	die "role ($role) not in range 0-3: $spec"
	    unless ($role >= 0 && $role <= 3);

	die "null username: $spec"
	    if ($user_spec eq '');

	my $user_obj = _resolve_user($user_spec);

	if (grep {$_->{user} eq $user_obj} @participants) {
	    warn "duplicate user: $user_spec"
	}
	else {
	    push (@participants, 
		  Elive::Entity::Participant->new({
		      user => $user_obj,
		      role => {roleId => $role},
		  }),
		);
	}
    }

    my $meeting = Elive::Entity::Meeting->insert
	({
	    name => $meeting_name,
	    password => $meeting_password,
	    facilitatorId => "${facilitator_obj}",
##	    privateMeeting => $private,
	    start => $start->epoch * 1000,
	    end => $end->epoch * 1000,
	 });
    
    print "created meeting: ".$meeting->name." with id ".$meeting->meetingId."\n";

    if (defined $max_talkers || defined $raise_hands) {
	
	my $meeting_parameters
	    = Elive::Entity::MeetingParameters->retrieve([$meeting->meetingId])
	    or die "Unable to retrieve meeting parameters for this meeting";
	
	$meeting_parameters->maxTalkers($max_talkers)
	    if (defined $max_talkers);

	$meeting_parameters->raiseHandOnEnter($raise_hands)
	    if (defined $raise_hands);

	$meeting_parameters->update;
    }

    if (@participants) {
	
	#
	# Create participant list
	#
	my $participants_str = join(';', @participants);
	print "participants: $participants_str\n";
	    
	my $participant_list = Elive::Entity::ParticipantList
	    ->insert({meetingId => $meeting->meetingId,
		      participants => \@participants,
		     });
    }
    else {
	print "no participants\n";
    }
};

Elive->disconnect;

exit(0);

########################################################################

sub _resolve_user {
    my $user_spec = shift;

    die 'usage: _get_user($user_name_or_id)'
	unless (defined $user_spec && $user_spec ne '');
    #
    # Try by username
    #
    my $user;

    if ($user_spec =~ m{^\d+$}) {
	#
	# Numeric id. Assume it's a user id
	#
	$user =  Elive::Entity::User->retrieve([$user_spec]);
    }
    else {
	#
	# Treat non-numeric as a loginName
	#
	$user = Elive::Entity::User->get_by_loginName($user_spec);
    }

    die "unkown user: $user_spec"
	unless ($user);

    return $user;
}
