#!/usr/bin/perl -w
# Plugin for TWiki Collaboration Platform, http://TWiki.org/
#
# Copyright (C) 2008-2009 Peter Thoeny, peter@twiki.net
#               2008-2009 Sopan Shewale sopan.shewale@gmail.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html
#
# Colas (http://colas.nahaboo.net)
# modifications from mailnotify script from Dec 2001 release:
# - email is now optional, is fetched from the user homepage
# - webs not beginning by a capital letter are ignored ( _default, ...)
# - no mail is sent to TWikiGuest
# - if user is a group, recurses through its members

# Set library paths in @INC, at compile time
BEGIN { unshift @INC, '.'; require 'setlib.cfg'; }

use TWiki;
use TWiki::Net;
use TWiki::Func;
use TWiki::Plugins;
use TWiki::Plugins::NotificationPlugin;
use TWiki::Render;

my $debug = !( @ARGV && $ARGV[0] eq "-q" );

$debug && print "TWiki mail notification\n";
$debug && print "- to suppress all normal output: mailnotify -q\n";

my $webName = "Main";
my $topic;
my $userName = "nobody";

my $twiki = new TWiki($userName);

TWiki::Func::writeDebug("START REGULAR NOTIFICATIONS");
TWiki::Func::writeDebug("===========================");

my @users = TWiki::Plugins::NotificationPlugin::getUsers();

my %notify;
foreach my $user (@users) {
    $notify{$user}{"web"} = join( ",",
        TWiki::Plugins::NotificationPlugin::getNotificationsOfUser( $user, 4 )
    );
    $notify{$user}{"topic"} = join( ",",
        TWiki::Plugins::NotificationPlugin::getNotificationsOfUser( $user, 3 )
    );
    $notify{$user}{"regex"} = join( ",",
        TWiki::Plugins::NotificationPlugin::getNotificationsOfUser( $user, 5 )
    );
}

my @weblist = TWiki::Func::getListOfWebs();

my $allChanges = "";
my %lastmodify;
my $dataDir = TWiki::Func::getDataDir();
foreach my $web (@weblist) {

    # Only process webs with normal names, i.e. not starting with '_'
    if ( TWiki::Func::webExists($web) ) {
        my $changes = TWiki::Func::readFile("$dataDir/$web/.changes");
        $lastmodify{$web} = TWiki::Func::readFile("$dataDir/$web/.mailnotify")
          || "0";
        my $currmodify = 0;
        my %exclude;

        foreach ( reverse split( /[\r\n]+/, $changes ) ) {
            my ( $topicName, $userName, $changeTime, $revision ) = split(/\t/);

            next if ( $exclude{"$web.$topicName"} );
            $currmodify = $changeTime if ( $changeTime > $currmodify );

            last if ( $changeTime <= $lastmodify{$web} );

            $allChanges .= "$web\t$_\n";
            $exclude{"$web.$topicName"} = 1;
        }

        # remove obsolete .lock files
        # &TWiki::Store::removeObsoleteTopicLocks( $web );
        # save date of the last modification
        TWiki::Func::saveFile( "$dataDir/$web/.mailnotify", $currmodify );
    }
}

my $skin = TWiki::Func::getSkin();

my $htmlTmpl = TWiki::Func::readTemplate( "htmlchanges", $skin );

$htmlTmpl = TWiki::Func::expandCommonVariables( $htmlTmpl, $topic );

my $htmlBefore = "";
my $htmlAfter  = "";
( $htmlBefore, $htmlWebTmpl, $htmlTopicTmpl, $htmlAfter ) =
  split( /%REPEAT%/, $htmlTmpl );

my $htmlEmailTmpl = TWiki::Func::renderText($htmlBefore);

$htmlAfter = TWiki::Func::renderText($htmlAfter);

my $from = TWiki::Func::getPreferencesValue("WIKIWEBMASTER");

my $scriptUrlPath = TWiki::Func::getScriptUrlPath;

foreach my $user (@users) {
    my $htmlEmailBody = $htmlEmailTmpl;
    $htmlEmailBody =~ s/%WIKIUSER%/$user/g;
    my $topiclist     = "";
    my $htmltopiclist = "";
    my $htmlregexlist = "";
    my $newtext;
    my %handled;
    my $count = 0;

    foreach my $line ( split( /\n/, $allChanges ) ) {
        my ( $web, $topicName, $userName, $changeTime, $revision ) =
          split( /\t/, $line );
        my $wikiuser = TWiki::Func::userToWikiName( $userName, 1 );
        foreach my $tweb ( split( /,/, $notify{$user}{"web"} ) ) {

            if ( $web eq $tweb ) {

                if ( !$handled{$tweb} ) {
                    $newText = $htmlWebTmpl;
                    $newText =~ s/%WEBNAME%/$web/g;
                    $newText = TWiki::Func::renderText($newText);
                    $htmlEmailBody .= $newText;
                    $handled{$tweb} = 1;
                }

                $newText = $htmlTopicTmpl;
                $newText =~ s/%TOPICNAME%/$topicName/g;
                $newText =~ s/%WEBNAME%/$web/g;
                $newText =~ s/%AUTHOR%/$wikiuser/g;
                $newText =~ s/%LOCKED%//g;
                my $time = TWiki::Func::formatGmTime($changeTime);
                $newText =~ s/%TIME%/$time/g;
                $newText =~ s/%REVISION%/1\.$revision/g;
                $newText = TWiki::Func::renderText($newText);

                my $head =
                  $twiki->{renderer}
                  ->summariseChanges( $userName, $web, $topicName,
                    $revision - 1,
                    $revision, 1 );

                $newText =~ s/%TEXTHEAD%/$head/g;
                $htmlEmailBody .= $newText;

                # new plain text for web
                $count++;
            }
        }
        foreach my $ttopic ( split( /,/, $notify{$user}{"topic"} ) ) {

            if ( "$web.$topicName" eq $ttopic ) {

                $newText = $htmlTopicTmpl;
                $newText =~ s/%TOPICNAME%/$topicName/g;
                $newText =~ s/%WEBNAME%/$web/g;
                $newText =~ s/%AUTHOR%/$wikiuser/g;
                $newText =~ s/%LOCKED%//g;
                my $time = TWiki::Func::formatGmTime($changeTime);
                $newText =~ s/%TIME%/$time/g;
                $newText =~ s/%REVISION%/1\.$revision/g;
                $newText = TWiki::Func::renderText($newText);
                my $head =
                  $twiki->{renderer}
                  ->summariseChanges( $userName, $web, $topicName,
                    $revision - 1,
                    $revision, 1 );
                $newText =~ s/%TEXTHEAD%/$head/g;
                $htmltopiclist .= $newText;
                $count++;
            }
        }
        foreach my $tregex ( split( /,/, $notify{$user}{"regex"} ) ) {
            if ( "$web.$topicName" =~ /$tregex/ ) {
                $newText = $htmlTopicTmpl;
                $newText =~ s/%TOPICNAME%/$topicName/g;
                $newText =~ s/%WEBNAME%/$web/g;
                $newText =~ s/%AUTHOR%/$wikiuser/g;
                $newText =~ s/%LOCKED%//g;
                my $time = &TWiki::formatGmTime($changeTime);
                $newText =~ s/%TIME%/$time/g;
                $newText =~ s/%REVISION%/1\.$revision/g;
                $newText = &TWiki::getRenderedVersion($newText);
                my $head =
                  $twiki->{renderer}
                  ->summariseChanges( $user, $web, $topic, $twiki->{BASE_REV},,
                    $twiki->{CURR_REV}, 1 );
                $newText =~ s/%TEXTHEAD%/$head/g;
                $htmlregexlist .= $newText;
                $count++;
            }
        }
    }

    if ( $count > 0 ) {
        $htmlEmailBody .= $htmlAfter;
        $htmlEmailBody =~ s/%TOPICLIST%/$htmltopiclist/goi;
        $htmlEmailBody =~ s/%REGEXLIST%/$htmlregexlist/goi;

        my $email = TWiki::Func::readTemplate("mailnotify");

        $email =~ s/%EMAILFROM%/$from/go;
        my $mail = &TWiki::Plugins::NotificationPlugin::getUserEmail($user);

        $email =~ s/%EMAILTO%/$mail/go;
        $email =~ s/%HTMLEMAILBODY%/$htmlEmailBody/go;
        $email = TWiki::Func::expandCommonVariables( $email, $topic );

        # change absolute addresses to relative ones & do some cleanup
        $email =~ s/(href=\")$scriptUrlPath/$1..\/../goi;
        $email =~ s/(action=\")$scriptUrlPath/$1..\/../goi;
        $email =~ s|( ?) *</*nop/*>\n?|$1|gois;

        $debug && print "- Sending mail notification to $user\n";
        &TWiki::Func::writeDebug("MAIL SENT TO $user ...");

        my $error = TWiki::Func::sendEmail($email);
        if ($error) {
            TWiki::Func::writeDebug("ERROR IN SENDING MAIL - $error");
            print STDERR "* $error\n";
            $debug && print "- End TWiki.$webName\n";
        }
    }
}

TWiki::Func::writeDebug("FINISH REGULAR NOTIFICATIONS");
TWiki::Func::writeDebug("============================");
$debug && print "End TWiki mail notification\n";

