#!/usr/bin/perl -wT
#
###############################################################################
#
# Copyright (C) 2003, Motorola. All Rights Reserved.
#
# FILE NAME     : autoregnotify
# PROGRAMMER(S) : Pablo Bertetti (apb026)
#
# DESCRIPTION:	
#
# The purpose of this script is to provide an add-on to the TWiki framework 
# that serves as an automatic way to add the logged user to the list of 
# notified users for the current topic of the current web.
#
###############################################################################
#
# MODIFICATION HISTORY:
#
# Date        |Person   |Change
# ------------+----------------------------------------------------------------
# 10-Feb-2003 |apb026   |First draft version
# 11-Feb-2003 |apb026   |Rework done from code inspection
#
###############################################################################

use strict;
use CGI::Carp qw(fatalsToBrowser);
use CGI;
use lib ( '.' );
use lib ( '../lib' );
use TWiki;

&main();

sub main
{

   my $query = new CGI;

   # Initialize the environment to use global vars
   &TWiki::initialize( $query->path_info(), $query->remote_user(), "", $query->url(), "" );

   # Check if the logged in user is authenticated and registered as a TWiki user
   if ( &TWiki::isGuest() || ! $TWiki::userToWikiList{$TWiki::userName} )
   # BEGIN: User is not authenticated or registered
   {
      my $url = &TWiki::getOopsUrl( $TWiki::webName, $TWiki::topicName, "oopsautoregnotify", "You must be authenticated and registered as a TWiki user to be added to the notification list" );
      TWiki::redirect( $query, $url );
      return;
   }
   # END: User is not authenticated or registered

   # Read WebNotify topic
   my ( $notifyMeta, $notifyText ) = &TWiki::Store::readTopic( $TWiki::webName, $TWiki::notifyTopicname ); 

   # Get the line which the user is in	
   $notifyText =~ m/(\t\*\s\Q$TWiki::wikiUserName\E.+)\r/;
   my $oldUserLine = $1;
	
   # Changes will be made over the newUserLine var
   my $newUserLine = $oldUserLine;

   # Main decision tree
   if ( ! $oldUserLine ) 
   # BEGIN: User is NOT in the notification topic
   {
      # Extract the user's email.
      my $userEmail;
      my ( $userTopicMeta, $userTopicText ) = &TWiki::Store::readTopic( $TWiki::mainWebname, $TWiki::wikiName ); 
		
      if ( $userTopicText =~ m/([A-Z0-9_\.\-]+@[A-Z0-9_\.\-]+)/i ) 
      # BEGIN: Valid e-mail is matched
      {
         $userEmail= $1;
      } 
      # END: Valid e-mail is matched
      else 
      # BEGIN: Valid e-mail couldn't be matched
      {
         my $url = &TWiki::getOopsUrl( $TWiki::webName, $TWiki::topicName, "oopsautoregnotify", "Could not find a valid email in the topic $TWiki::mainWebname.$TWiki::wikiName" );
         TWiki::redirect( $query, $url );
         return;
      } 
      # END: Valid e-mail couldn't be matched

      # Redefine oldUserLine as the first notification line found 
      $notifyText =~ m/(\t\*.+)/;
      $oldUserLine = $1;

      # Define newUserline as the oldUserLine plus the new notification line
      $newUserLine = "\t* $TWiki::wikiUserName - $userEmail + $TWiki::topicName\r\n$oldUserLine";
   } 
   # END: User is NOT in the notification topic
   else 
   # BEGIN: User IS in the notification topic
   {
      if ( $oldUserLine =~ m/\@[^-\+]+$/ ) 
      # BEGIN: User is notified for the entire web
      {
         # Notification topic is left as-is, since the user is already notified for the topic
      } 
      # END: User is notified for the entire web
      else 
      # BEGIN: User is NOT notified for the entire web
      {
         if ( $oldUserLine =~ m/\+/ ) 
         # BEGIN: User is notified only for specific topics
         {
            if ( $oldUserLine =~ m/-.+\Q$TWiki::topicName\E/ ) 
            # BEGIN: Topic name is already in the line
            {
               # Notification topic is left as-is, since the user is already notified for the topic
            } 
            # END: Topic name is already in the line
            else 
            # BEGIN: Topic name is NOT in the line 
            {
               # Add the topic to the line
               $newUserLine .= " $TWiki::topicName";
            } 
            # END: Topic name is NOT in the line 
         } 
         # END: User is notified only for specific topics
         else 
         # BEGIN: User is notified for the entire web but excluding specific topics
         {
            if ($oldUserLine =~ m/-.+\Q$TWiki::topicName\E/) 
            # BEGIN: Topic name is present in the line
            {
               # Remove it from the line
               $newUserLine =~ s/(-.*)\s\Q$TWiki::topicName\E/$1/g;

               # Remove the - in case it was the only one topic
               $newUserLine =~ s/\s*-\s*$//;
            } 
            # END: Topic name is present in the line
            else 
            # BEGIN: Topic name is not present in the line
            {
               # Notification topic is left as-is, since the user is already notified for the topic
            } 
            # END: Topic name is not present in the line
         } 
         # END: User is notified for the entire web but excluding specific topics
      } 
      # END: User is NOT notified for the entire web
   } 
   # END: User IS in the notification topic

   # Check if there are resulting changes that must be applied to the notification topic
   if ($oldUserLine ne $newUserLine)
   # BEGIN: Changes detected between oldUserLine and newUserLine
   {
      # Propagate the changes on the line to the topic text
      $notifyText =~ s/\Q$oldUserLine\E/$newUserLine/;

      # Check if the notification topic is being updated by another user
      my( $lockUser, $lockTime ) = &TWiki::Store::topicIsLockedBy( $TWiki::webName, $TWiki::notifyTopicname );

      if ( $lockUser )
      # BEGIN: Notification topic is locked
      {
         $lockUser = &TWiki::userToWikiName( $lockUser );
         my $url = &TWiki::getOopsUrl( $TWiki::webName, $TWiki::topicName, "oopsautoregnotify", "Topic $TWiki::webName.$TWiki::notifyTopicname is locked by another user ($lockUser)" );
         TWiki::redirect( $query, $url );
         return;
      }
      # END: Notification topic is locked

      # Save the notification topic
      my $error = &TWiki::Store::saveTopic( $TWiki::webName, $TWiki::notifyTopicname, $notifyText, $notifyMeta, "", "on", "" );

      # Check for save erros
      if( $error ) {
      # BEGIN: Probable error from RCS
         my $url = &TWiki::getOopsUrl( $TWiki::webName, $TWiki::notifyTopicname, "oopssaveerr", $error );
         TWiki::redirect( $query, $url );
         return;
      }
      # END: Probable error from RCS 
   }
   # END: Changes detected between oldUserLine and newUserLine

   # Redirect to the original topic
   TWiki::redirect( $query, &TWiki::getViewUrl( $TWiki::webName, $TWiki::topicName ) );
   return;
}		   

