#!%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 utf8;
use POSIX qw(locale_h);
use HTML::Template;
use locale;
use Locale::gettext;
use CGI;
use CGI::Session;
use strict;

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::Mail;
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 $mail_config = $vhffs->get_config->get_service('mail');
my $domain = $cgi->param('name');

my $template;

my $mail = Vhffs::Services::Mail::get_by_mxdomain( $vhffs , $domain );

unless( defined $mail ) {
	$template = new HTML::Template( filename => $templatedir.'/panel/misc/simplemsg.tmpl' );
	$template->param( MESSAGE => sprintf( gettext('Unable to get information on mail domain %s'), $domain ) );
} elsif( ! $user->can_view($mail) ) {
	$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 {
    my $catchall_type = lc($mail_config->{allowed_catchall});
    $catchall_type = 'domain' unless(defined $catchall_type and $catchall_type ne '');

    if( defined $cgi->param('modify_catchall_submit') ) {
        update_catchall($catchall_type);
    } elsif( defined $cgi->param('update_box_submit') ) {
        update_box();
    } elsif(defined $cgi->param('delete_box_submit')) {
        delete_box();
    } elsif(defined $cgi->param('add_box_submit')) {
        add_box();
    } elsif(defined $cgi->param('update_forward_submit')) {
        update_forward();
    } elsif(defined $cgi->param('delete_forward_submit')) {
        delete_forward();
    } elsif(defined $cgi->param('add_forward_submit')) {
        add_forward();
    }

	$template = new Vhffs::Panel::Template( filename => $templatedir."/panel/mail/prefs.tmpl",
        die_on_bad_params => 0, global_vars => 1);

    $panel->set_title( gettext("Mail Administration for domain ") );
	$template->param( VALUE_DOMAIN => $mail->get_domain );

    $template->param( CATCHALL_TYPE => $catchall_type );
	$template->param( SUBTITLE_CATCHALL => gettext("Catchall address") );
	$template->param( VALUE_CATCHALL => $mail->get_catchall );
	$template->param( TEXT_CATCHALL_EXPLAIN => gettext("Enter a mail address to catch all email for this domain") );
	$template->param( TEXT_CATCHALL => gettext("Catchall mail") );


	$template->param( SUBTITLE_ACCOUNTS => gettext("Accounts") );
	$template->param( TEXT_ACCOUNTS_LIST => gettext("List all accounts") );
	$template->param( TEXT_ACCOUNTS_ADD => gettext("Add an account") );
	
	$template->param( TEXT_ACCOUNT_LOCALPART => gettext("Local Part for this account") );
	$template->param( TEXT_ACCOUNT_PASSWORD => gettext("Password") );


	
	$template->param( SUBTITLE_FORWARDS => gettext("Forwards") );
	$template->param( TEXT_FORWARD_LIST => gettext("List all forwardings for this domain") );
	$template->param( TEXT_FORWARD_ADD => gettext("Add a forward on this domain") );
	
	$template->param( TEXT_FORWARD_FORM_LOCALPART => gettext("Local Part") );
	$template->param( TEXT_FORWARD_FORM_FORWARD => gettext("Forward mail") );



#	$template->param( TEXT_SEND => gettext("Modify") );
	$template->param( TEXT_CHANGE_CATCHALL => gettext("Change catchall forward") );
	$template->param( TEXT_ADD_ACCOUNT => gettext("Add a popbox to this domain") );
	$template->param( TEXT_ADD_FORWARD => gettext("Add a forward on this domain") );


	$template->param( TEXT_DELETE_MAIL => gettext("Delete this mail domain") );
	$template->param( TEXT_BEFORE_DELETE => gettext("This action is non-reversible. This mail area will be DESTROYED.") );
	$template->param( ASK_DELETE_WEB => gettext("Are you SURE you want DELETE this Mail Area ?") );
	$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 => $mail->get_oid );
    $template->param( TEXT_ACL_ADMIN => gettext("Admin Rights on this object (ACL)") );
    $template->param( EXPLAIN_ADMIN_ACL => gettext("You can Manage rights on this service for each user in the VHFFS database. Please read help before manage it.") );
    $template->param( ADMIN_ACL => gettext( "Ok, go to ACL admin" ) );



	my $output = "";
	my @boxes = sort { $a->{local_part} cmp $b->{local_part} } (values %{$mail->get_boxes});
	foreach my $bo ( @boxes )  {
		$bo->{active} = ($bo->{state} == Vhffs::Constants::ACTIVATED);
		$bo->{statestr} = Vhffs::Functions::status_string_from_status_id($bo->{state});
	}

    $template->param( BOXES => ( \@boxes ) );
    $template->param( ANTIVIRUS_FEATURE => ($mail_config->{'use_novirus'} eq 'yes' ) );
    $template->param( ANTISPAM_FEATURE => ($mail_config->{'use_nospam'} eq 'yes' ) );

	my @forwards = sort { $a->{local_part} cmp $b->{local_part} } (values %{$mail->get_forwards});
    $template->param( FORWARDS => ( \@forwards ) );

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

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


# Action handling subs

sub update_catchall {
    my $type = shift;
    # User wants to modify catchall address.
    if(!$user->can_modify($mail)) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        if($type eq 'none') {
            $panel->add_error( gettext('Catchall isn\'t enabled on this platform') );
            return;
        }
        my $catchall = $cgi->param('catchall');
        if(!defined($catchall)) {
            $panel->add_error( gettext('CGI Error !') );
        } else {
            if($type eq 'domain' && $catchall ne '') {
                if( ! $mail->exists_box($catchall) || $mail->get_box_status($catchall) != Vhffs::Constants::ACTIVATED) {
                    $panel->add_error( gettext('Selected mailbox doesn\'t exist for this mail domain or is not yet active.') );
                    return;
                }
                $catchall .= "\@$domain";
            }
            if($mail->set_catchall($catchall) < 0) {
                $panel->add_error( sprintf( gettext('%s is not a correct mail address'), $catchall) );
            } elsif($mail->commit() < 0) {
                $panel->add_error( gettext("An error occured while updating the mail domain") );
            } else {
               $panel->add_info(gettext('Catchall address successfully changed'));
            }
        }
    }
}

sub add_box {
   if(!$user->can_modify($mail)) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        my $box = $cgi->param('localpart');
        my $passwd = $cgi->param('box_password');
        if(!defined $box || !defined $passwd) {
            $panel->add_error( gettext('CGI Error !') );
        } elsif($mail->addbox( $box, $passwd ) < 0 ) {
            $panel->add_error(gettext( "This box already exists for this domain or parameters are not valid. Check your domain." ) );
        } else {
            $panel->add_info( gettext('Box successfully added') );
        }
    }
}

sub update_box {
    # User wants to update information about a box
    my $box = $cgi->param('localpart');
    unless( $user->can_modify($mail) && $mail->get_box_status( $box ) == Vhffs::Constants::ACTIVATED ) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        my $passwd = $cgi->param('box_password');
        my $use_antispam = $cgi->param('use_antispam');
        my $use_antivirus = $cgi->param('use_antivirus');
        if(!defined($box) || !defined($passwd) ||
            ($mail_config->{'use_novirus'} eq 'yes' && !defined($use_antivirus)) ||
            ($mail_config->{'use_nospam'} eq 'yes' && !defined($use_antispam)) ) {
            $panel->add_error( gettext('CGI Error !') );
        } else {
            if($passwd !~ /^\s*$/) {
                if($mail->change_box_password( $box, $passwd ) < 0) {
                    $panel->add_error( gettext('Could not change box password') );
                } else {
                    $panel->add_info( gettext('Box password updated') );
                }
            }
            if(defined $use_antispam) {
                # We've to explicitely pass 1 or 0 to avoid passing '' to underlying SQL query
                if( $mail->set_spam_status($box, ($use_antispam eq 'yes' ? 1 : 0 ) ) < 0) {
                    $panel->add_error( sprintf( gettext('Could not update spam status for box %s'), $box ) );
                } else {
                    $panel->add_info( gettext('Spam status updated') );
                }
            }
            if(defined $use_antivirus) {
                if( $mail->set_virus_status($box, ($use_antivirus eq 'yes' ? 1 : 0) ) < 0) {
                    $panel->add_error( sprintf( gettext('Could not update antivirus status for box %s'), $box ) );
                } else {
                    $panel->add_info( gettext('Virus status updated') );
                }
            }
        }
    }
}

sub delete_box {
    # User wants to delete a box
    my $box = $cgi->param('localpart');
    unless( $user->can_modify($mail) && $mail->get_box_status( $box ) == Vhffs::Constants::ACTIVATED ) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        if(!defined $box) {
            $panel->add_error( gettext('CGI Error !') );
        } elsif($mail->set_box_status($box, Vhffs::Constants::TO_DELETE) < 0) {
            $panel->add_error( sprintf(gettext('Unable to delete box %s'), $box) );
        } else {
            $panel->add_info( sprintf(gettext('Box %s deleted'), $box) );
        }
    }
}

sub add_forward {
    if(!$user->can_modify($mail)) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        my $local = $cgi->param('localpart');
        my $remote = $cgi->param('forward');
        if(!defined $local || !defined $remote) {
            $panel->add_error( gettext('CGI Error !') );
        } elsif($mail->addforward( $local, $remote ) < 0) {
            $panel->add_error( sprintf(gettext('Unable to add forward %s'), $local) );
        } else {
            $panel->add_info( gettext('Forward added') );
        }
    }
}

sub update_forward {
    if(!$user->can_modify($mail)) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        my $local = $cgi->param('localpart');
        my $remote = $cgi->param('forward');
        if(!defined $local || !defined $remote) {
            $panel->add_error( gettext('CGI Error !') );
        } elsif($mail->change_forward( $local, $remote ) < 0) {
            $panel->add_error( sprintf(gettext('Unable to modify forward %s' ), $local ) );
        } else {
            $panel->add_info( sprintf(gettext('Forward %s successfully updated'), $local ) );
        }
    }
}

sub delete_forward {
    if(!$user->can_modify($mail)) {
        $panel->add_error( gettext('You are not allowed to modify this object') );
    } else {
        my $local = $cgi->param('localpart');
        if(!defined $local) {
            $panel->add_error( gettext('CGI Error !') );
        } elsif($mail->delforward($local) < 0) {
            $panel->add_error( sprintf(gettext('Unable to delete forward %s'), $local) );
        } else {
            $panel->add_info( sprintf(gettext('Forward %s deleted'), $local) );
        }
    }
}
