<%init>

use Data::ICal;
use Data::ICal::Entry::Todo;
use Data::ICal::Entry::Event;
use Date::ICal;

my ($UserId, $SearchId, $MagicNumber);
my $arg = $m->dhandler_arg;

if ($arg =~ m{^(\d+)@(\d+)/(.*)$}) {
    $UserId = $1;
    $SearchId = $2;
    $MagicNumber = $3;
} elsif ($arg =~ m{^(\d+)/(.*)}) {
    $UserId = $1;
    $MagicNumber = $2;
} else {
    Abort("Corrupted URL.");
}

my $CurrentUser = new RT::CurrentUser();
$CurrentUser->LoadById($UserId);
my $user = $CurrentUser->Name;

# if no user, abort
unless ($CurrentUser->Id) {
    $RT::Logger->error("No such user id $UserId from $ENV{'REMOTE_ADDR'}");
    $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
    $m->abort;
}

# verify user has LoadSavedSearch right
if ($SearchId and not $CurrentUser->HasRight( Right => 'LoadSavedSearch',
                                              Object=> $RT::System )) {
    $RT::Logger->error("not enough rights for user $user from $ENV{'REMOTE_ADDR'}");
    $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
    $m->abort;
}


# if MagicNumber doesn't match the one stored in database, abort
my $Search;
my $ICalAttribute;
if ($SearchId) {
    $Search = $CurrentUser->Attributes->WithId($SearchId);
    $ICalAttribute = $Search->FirstAttribute('ICalURL');
} else {
    $ICalAttribute = $CurrentUser->FirstAttribute('ICalURL');
}

unless ($ICalAttribute) {
    $RT::Logger->error("No such ICal feed for $user from $ENV{'REMOTE_ADDR'}");
    $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
    $m->abort;
}


if ($MagicNumber ne $ICalAttribute->Content) {
    $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}");
    $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
    $m->abort;
}

my $Tickets   = RT::Tickets->new($CurrentUser);
my $Reminders = RT::Tickets->new($CurrentUser);

if ($Search) {
    $Tickets->FromSQL( $Search->SubValue('Query') );
} else {
    $Tickets->LimitStatus( VALUE => 'open' );
    $Tickets->LimitStatus ( VALUE => 'new');
    $Tickets->LimitStatus ( VALUE => 'stalled');

    $Tickets->LimitOwner ( VALUE => $CurrentUser->Id);
    $Tickets->LimitOwner ( VALUE => 'Nobody');

    $Tickets->LimitDue(OPERATOR => ">", VALUE => 0 );

    $Reminders = RT::Tickets->new($CurrentUser);
    $Reminders->FromSQL('(Owner = "Nobody" OR Owner = "'.$CurrentUser->Name.'")' .
			    ' AND Type = "reminder" AND (Status = "new" OR Status = "open") AND Due > "1970-01-01"'); 
    $Reminders->OrderBy(FIELD => 'Due', ORDER => 'ASC');
}

$Tickets->OrderBy(FIELD => 'Due', ORDER => 'ASC');

my $calendar = Data::ICal->new();

my ($uid) = $RT::WebURL =~ m{https?://([^:]+)};

while (my $Ticket = $Tickets->Next ) {
    
    my %vtodo = (
	summary    => $Ticket->Subject ? $Ticket->Subject : '',
	dtstart    => Date::ICal->new( epoch => $Ticket->CreatedObj->Unix )->ical,
	url        => "${RT::WebURL}/Ticket/Display.html?id=" . $Ticket->id,
	uid        => Date::ICal->new( epoch => time() )->ical() . "-" . $Ticket->Id . "@" . $uid,
	categories => $Ticket->QueueObj->Name,
    );

    $vtodo{due} = Date::ICal->new( epoch => $Ticket->DueObj->Unix )->ical,
        if $Ticket->DueObj;

    if ($Ticket->OwnerObj->Id != $RT::Nobody->Id and $Ticket->OwnerObj->EmailAddress) {
	$vtodo{organizer} = "MAILTO:" . $Ticket->OwnerObj->EmailAddress;
	$vtodo{attendee} = "MAILTO:" . $Ticket->OwnerObj->EmailAddress;
    } elsif ($Ticket->QueueObj->CommentAddress) {
	$vtodo{organizer} = "MAILTO:" . $Ticket->QueueObj->CommentAddress;
	$vtodo{attendee} = "MAILTO:" . $Ticket->QueueObj->CommentAddress; 
    }

    $vtodo{priority} = $Ticket->Priority
	if $Ticket->Priority;

    my $vtodo = Data::ICal::Entry::Todo->new();
    $vtodo->add_properties(%vtodo);
    $calendar->add_entry($vtodo);
}

while ( my $Reminder = $Reminders->Next ) {
    my $Ticket  = $Reminder->RefersTo->First->TargetObj;
    
    my %event = (
	summary => $Reminder->Subject ? $Reminder->Subject : '',
	url        => "${RT::WebURL}/Ticket/Display.html?id=" . $Ticket->id,
	uid        => Date::ICal->new( epoch => time() )->ical() . "-" . $Reminder->Id . "@" . $uid,
	categories => $Ticket->QueueObj->Name,
	dtstart     => Date::ICal->new( epoch => $Reminder->DueObj->Unix )->ical,
    );

    my $event = Data::ICal::Entry::Event->new();
    $event->add_properties(%event);
    $calendar->add_entry($event);

}

my $cal = $calendar->as_string;

$r->content_type('text/calendar;charset=utf-8');
$m->clear_buffer();
$m->out($cal);
$m->abort; 

</%init>
