#!%PERL% -w
# Copyright (c) vhffs project and its contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without 
# modification, are permitted provided that the following conditions 
# are met:
#
# 1. Redistributions of source code must retain the above copyright 
#   notice, this list of conditions and the following disclaimer.
#2. Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in 
#   the documentation and/or other materials provided with the 
#   distribution.
#3. Neither the name of vhffs nor the names of its contributors 
#   may be used to endorse or promote products derived from this 
#   software without specific prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
# POSSIBILITY OF SUCH DAMAGE.


use strict;
use utf8;
use POSIX qw(locale_h);
use HTML::Template;
use locale;
use Locale::gettext;
use CGI;
use CGI::Session;
use Encode;

use lib '%VHFFS_LIB_DIR%';
use Vhffs::User;
use Vhffs::Group;
use Vhffs::Main;
use Vhffs::Panel::Main;
use Vhffs::Panel::Menu;
use Vhffs::Panel::Template;
use Vhffs::Panel::Object;
use Vhffs::Services::MailingList;
use Vhffs::Acl;
use Vhffs::Constants;

my $panel = new Vhffs::Panel::Main();
exit 0 unless $panel;
my $session = $panel->get_session;
exit 0 unless $session;

my $vhffs = $panel->{'vhffs'};
my $user = $panel->{'user'};
my $cgi = $panel->{'cgi'};
my $templatedir = $panel->{'templatedir'};

my $domain = $cgi->param("domain");
my $lpart = $cgi->param("local");
my $name = $cgi->param("name");

my $template;

#defined name in CGI overwrite lpart and domain cgi
if( defined $name ) {
	( $lpart , $domain ) =  ( $name =~ /(.+)\@(.+)/ );
}

my $list = Vhffs::Services::MailingList::get_by_mladdress( $vhffs , $lpart , $domain );

unless( defined $list ) {
	$template = new HTML::Template( filename => $templatedir.'/panel/misc/simplemsg.tmpl' );
	$template->param( MESSAGE => sprintf( gettext('Mailing list %s@%s not found'), $lpart, $domain) );
} elsif( !$user->can_view( $list ) ) {
	$template = new HTML::Template( filename => $templatedir.'/panel/misc/simplemsg.tmpl' );
	$template->param( MESSAGE => gettext( 'You\'re not allowed to do this, object is not in active state or you don\'t have enough ACL rights' ) );
} else {
    if(defined $cgi->param('options_submit')) {
        update_ml_options();
    } elsif(defined $cgi->param('delete_submit')) {
        delete_member();
    } elsif(defined $cgi->param('change_rights_submit')) {
        change_rights();
    } elsif(defined $cgi->param('add_members_submit')) {
        add_members();
    }
    
	$template = new Vhffs::Panel::Template( filename => $templatedir."/panel/mailinglist/prefs.tmpl",
        die_on_bad_params => 0, global_var => 1);

    $panel->set_title( sprintf(gettext('Administration for list %s'),
            $list->get_localpart . "\@" . $list->get_domain) );
	
	$template->param( VALUE_DOMAIN => $list->get_domain );
	$template->param( VALUE_LOCALPART => $list->get_localpart );
	
	$template->param( SUBTITLE_OPTIONS => gettext("Options") );
	$template->param( TEXT_SUBSCRIBE_CONTROL => gettext("Subscribe control:") );
	$template->param( TEXT_SUBSCRIBE_NO_APPROVAL_REQUIRED => gettext("Open, no approval required") );
	$template->param( TEXT_SUBSCRIBE_APPROVAL_REQUIRED => gettext("Open, approval required") );
	$template->param( TEXT_SUBSCRIBE_CLOSED => gettext("Closed") );
	$template->param( TEXT_POSTING_CONTROL => gettext("Posting control:") );
	$template->param( TEXT_POSTING_OPEN_ALL => gettext("Open for everyone") );
	$template->param( TEXT_POSTING_MODERATED_ALL => gettext("Moderated for everyone") );
	$template->param( TEXT_POSTING_OPEN_MEMBERS_MODERATED_OTHERS => gettext("Open for members, moderated for non-members") );
	$template->param( TEXT_POSTING_MEMBERS_ONLY => gettext("Members only") );
	$template->param( TEXT_POSTING_MEMBERS_ONLY_MODERATED => gettext("Members only and moderated") );
	$template->param( TEXT_POSTING_ADMINS_ONLY => gettext("Admins only") );
	$template->param( VALUE_SUBSCRIBE_NO_APPROVAL_REQUIRED => Vhffs::Constants::ML_SUBSCRIBE_NO_APPROVAL_REQUIRED );
	$template->param( VALUE_SUBSCRIBE_APPROVAL_REQUIRED => Vhffs::Constants::ML_SUBSCRIBE_APPROVAL_REQUIRED );
	$template->param( VALUE_SUBSCRIBE_CLOSED => Vhffs::Constants::ML_SUBSCRIBE_CLOSED );
	$template->param( VALUE_POSTING_OPEN_ALL => Vhffs::Constants::ML_POSTING_OPEN_ALL );
	$template->param( VALUE_POSTING_MODERATED_ALL => Vhffs::Constants::ML_POSTING_MODERATED_ALL );
	$template->param( VALUE_POSTING_OPEN_MEMBERS_MODERATED_OTHERS => Vhffs::Constants::ML_POSTING_OPEN_MEMBERS_MODERATED_OTHERS );
	$template->param( VALUE_POSTING_MEMBERS_ONLY => Vhffs::Constants::ML_POSTING_MEMBERS_ONLY );
	$template->param( VALUE_POSTING_MEMBERS_ONLY_MODERATED => Vhffs::Constants::ML_POSTING_MEMBERS_ONLY_MODERATED );
	$template->param( VALUE_POSTING_ADMINS_ONLY => Vhffs::Constants::ML_POSTING_ADMINS_ONLY );
	$template->param( SELECTED_SUBSCRIBE_NO_APPROVAL_REQUIRED => "selected" ) if( $list->{sub_ctrl} == Vhffs::Constants::ML_SUBSCRIBE_NO_APPROVAL_REQUIRED );
	$template->param( SELECTED_SUBSCRIBE_APPROVAL_REQUIRED => "selected" ) if( $list->{sub_ctrl} == Vhffs::Constants::ML_SUBSCRIBE_APPROVAL_REQUIRED );
	$template->param( SELECTED_SUBSCRIBE_CLOSED => "selected" ) if( $list->{sub_ctrl} == Vhffs::Constants::ML_SUBSCRIBE_CLOSED );
	$template->param( SELECTED_POSTING_OPEN_ALL => "selected" ) if( $list->{post_ctrl} == Vhffs::Constants::ML_POSTING_OPEN_ALL );
	$template->param( SELECTED_POSTING_MODERATED_ALL => "selected" ) if( $list->{post_ctrl} == Vhffs::Constants::ML_POSTING_MODERATED_ALL );
	$template->param( SELECTED_POSTING_OPEN_MEMBERS_MODERATED_OTHERS => "selected" ) if( $list->{post_ctrl} == Vhffs::Constants::ML_POSTING_OPEN_MEMBERS_MODERATED_OTHERS );
	$template->param( SELECTED_POSTING_MEMBERS_ONLY => "selected" ) if( $list->{post_ctrl} == Vhffs::Constants::ML_POSTING_MEMBERS_ONLY );
	$template->param( SELECTED_POSTING_MEMBERS_ONLY_MODERATED => "selected" ) if( $list->{post_ctrl} == Vhffs::Constants::ML_POSTING_MEMBERS_ONLY_MODERATED );
	$template->param( SELECTED_POSTING_ADMINS_ONLY => "selected" ) if( $list->{post_ctrl} == Vhffs::Constants::ML_POSTING_ADMINS_ONLY );

	$template->param( TEXT_OPENARCHIVE => gettext("Public archives") );
	$template->param( TEXT_REPLYTO => gettext("Reply to: on list") );
	$template->param( TEXT_PREFIX  => gettext("Prefix on subject") );
	$template->param( VALUE_PREFIX  => $list->get_prefix );

	$template->param( TEXT_SUBMIT_PREFS => gettext("Save options") );

	$template->param( VALUE_SIGNATURE => $list->get_signature );
	$template->param( TEXT_SUBMIT_SIGNATURE => gettext("Update signature") );
	
	$template->param( TITLE_MEMBERS => gettext("Manage members") );
	$template->param( TITLE_LIST_MEMBERS => gettext("List all members") );
	$template->param( TITLE_ADD_MEMBERS => gettext("Add members") );
	$template->param( TEXT_ADD_MEMBERS => gettext("Addresses (one per line)") );
	$template->param( BUTTON_ADD_MEMBERS => gettext("Add them !") );

	my $emaillist = '';
	my $group = Vhffs::Group::get_by_gid( $vhffs , $list->get_owner_gid );
	if( defined $group )  {
		foreach ( @{$group->get_users} )  {
			$emaillist .= $_->{'mail'}."\n";
		}
	}
	$template->param( PROJECT_MEMBERS_LIST => $emaillist );
	$template->param( PUBLIC_ARCHIVE => $list->get_open_archive == 1 );
	$template->param( REPLY_TO => $list->get_replyto == 1 );

	my @subs = values(%{$list->get_members});
    
    $template->param( LOCAL_PART => $list->get_localpart );
    $template->param( DOMAIN => $list->get_domain );

    $template->param( ML_RIGHT_SUB_WAITING_FOR_REPLY => Vhffs::Constants::ML_RIGHT_SUB_WAITING_FOR_REPLY);
    $template->param( ML_RIGHT_SUB_WAITING_FOR_VALIDATION => Vhffs::Constants::ML_RIGHT_SUB_WAITING_FOR_VALIDATION);
    $template->param( ML_RIGHT_SUB => Vhffs::Constants::ML_RIGHT_SUB);
    $template->param( ML_RIGHT_SUB_WAITING_FOR_DEL => Vhffs::Constants::ML_RIGHT_SUB_WAITING_FOR_DEL);
    $template->param( ML_RIGHT_ADMIN => Vhffs::Constants::ML_RIGHT_ADMIN);
    

    $template->param( MEMBERS => \@subs );

    $template->param( HOWMANY_MEMBERS => scalar(@subs) );

    $template->param( TEXT_DELETE_LIST => gettext("Delete this list") );
    $template->param( TEXT_BEFORE_DELETE => gettext("This action is non-reversible. This mailing list will be DESTROYED.") );
    $template->param( ASK_DELETE_WEB => gettext("Are you SURE you want DELETE this mailing list ?") );
    $template->param( YES => gettext("Yes I'm sure of what I do") );
    $template->param( NO => gettext("No, I'm not sure, I prefer to keep this project.") );
    $template->param( TEXT_DELETE => gettext("Delete") );

    $template->param( VALUE_OID => $list->get_oid );
    $template->param( TEXT_ACL_ADMIN => "Admin Rights on this object (ACL)" );
    $template->param( EXPLAIN_ADMIN_ACL => "You can Manage rights on this service for each user in the VHFFS database. Please read help before manage it." );
    $template->param( ADMIN_ACL => "Ok, go to ACL admin" );

	my $adminpart = Vhffs::Panel::Object::admin_part( $panel, $list );
	$template->param( ADMIN_PART => $adminpart->output ) if( defined $adminpart );
}

$panel->build( $template );
$panel->display;


sub update_ml_options {
    my $prefix = Encode::decode_utf8( $cgi->param('prefix') );
    my $sub_ctrl = $cgi->param('subscribe_control');
    my $post_ctrl = $cgi->param('posting_control');
    my $sig = Encode::decode_utf8( $cgi->param('signature') );

    if(!$user->can_modify($list)) {
        $panel->add_error( gettext( 'You\'re not allowed to do this, object is not in active state or you don\'t have enough ACL rights' ) );
        return;
    }

    if(!defined $prefix || !defined $sub_ctrl || !defined $post_ctrl || !defined $sig) {
      $panel->add_error( gettext('CGI Error !') );
      return;
    }
    $list->set_prefix($prefix);
    $list->set_sub_ctrl($sub_ctrl);
    $list->set_post_ctrl($post_ctrl);
    $list->set_open_archive(defined $cgi->param('public_archive') ? 1 : 0);
    $list->set_replyto(defined $cgi->param('reply_to') ? 1 : 0);
    $list->set_signature($sig);
    if($list->commit() < 0) {
      $panel->add_error( gettext('Unable to save object') );
    } else {
      $panel->add_info( gettext('List updated') );
    }
}

sub delete_member {
    my $member = $cgi->param('member');

    if(!$user->can_modify($list)) {
        $panel->add_error( gettext( 'You\'re not allowed to do this, object is not in active state or you don\'t have enough ACL rights' ) );
        return;
    }

    if(!defined $member) {
        $panel->add_error( gettext('CGI Error !') );
        return;
    }

    if( $list->del_sub($member) < 0 ) {
        $panel->add_error('An error occured while deleting this subscriber');
    } else {
        $panel->add_info( sprintf( gettext('Subscriber %s deleted'), $member ) );
    }
}

sub change_rights {
    my $member = $cgi->param('member');
    my $right = $cgi->param('right');

    if(!$user->can_modify($list)) {
        $panel->add_error( gettext('You are not allowed to manager subscribers\' rights (ACL rights)') );
        return;
    }

    if(!defined $member || !defined $right) {
        $panel->add_error( gettext('CGI Error !') );
        return;
    }

    if( $list->change_right_for_sub( $member, $right ) < 0) {
        $panel->add_error( sprintf( gettext('Unable to change rights for subscriber %s'), $member ) );
    } else {
        $panel->add_info( sprintf( gettext('Rights for subscriber %s updated'), $member ) );
    }
}

sub add_members {
    my $memberlist = $cgi->param('members');

    if(!$user->can_modify($list)) {
        $panel->add_error( gettext('You are not allowed to add members (ACL rights)') );
        return;
    }

    if(!defined($memberlist)) {
        $panel->add_error( gettext('CGI Error !') );
        return;
    }

    if($memberlist =~ /^\s*$/) {
        $panel->add_error( gettext('You need to enter at least one new member') );
        return;
    }

    my @members = split /\r\n/, $memberlist;
    my $listengineconfig = $vhffs->get_config->get_listengine;

    foreach my $member ( @members )  {
        chomp $member;
	( $member ) = ( $member =~ /^\s*([^\s]+)\s*$/ );
	$member = lc $member;
        if( ! Vhffs::Functions::valid_mail( $member ) )  {
       	    $panel->add_error( sprintf( gettext('%s is not a valid mail'), $member ) )
        }  elsif( $list->add_sub( $member , Vhffs::Constants::ML_RIGHT_SUB )  < 0 ) {
       	    $panel->add_error( sprintf( gettext( '%s is already a member of this list' ), $member ) );
        } else {
       	    $panel->add_info( sprintf( gettext( '%s has been added' ), $member ) );
            Vhffs::Functions::send_mail(
		$vhffs,
       	        $listengineconfig->{'listmaster'},
                $member,
       	        undef,
                sprintf(gettext('[%s] You\'ve been added to the list %s'), $list->get_prefix, $list->get_localpart.'@'.$list->get_domain),
       	        sprintf(gettext("Greetings,\n\nYou've been added to the list %s on platform %s.\n\nYou may get some help on listengine by sending an email to %s-request\@%s with subject help.\n\nCheers.\n"), $list->get_localpart.'@'.$list->get_domain, $vhffs->get_config->get_host_name, $list->get_localpart, $list->get_domain),
                );
        }
    }
}

