#!%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 locale;
use Locale::gettext;
use CGI;
use CGI::Session;
use Encode;
use strict;

use lib '%VHFFS_LIB_DIR%';
use Vhffs::Functions;
use Vhffs::Group;
use Vhffs::Main;
use Vhffs::Panel::Main;
use Vhffs::Panel::Group;
use Vhffs::Panel::Object;
use Vhffs::Panel::Template;
use Vhffs::Services::MailGroup;
use Vhffs::Tag;
use Vhffs::Tag::Category;
use Vhffs::Tag::Request;
use Vhffs::User;

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 $templatedir = $panel->{'templatedir'};
my $cgi = $panel->{'cgi'};
my $template;

my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );

unless( defined $group ) {
	$template = new HTML::Template( filename => $templatedir.'/panel/misc/simplemsg.tmpl' );
	$template->param( MESSAGE => gettext( "Error. This group doesn't exists") );
} elsif( !$user->can_view( $group ) ) {
	$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 {

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

	if( defined( $cgi->param( 'update_desc_submit' ) ) ) {
		# Description modification
		unless( $user->can_modify( $group ) ) {
			$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		} else {
			my $description = Encode::decode_utf8( $cgi->param( 'description' ) );
			my $realname = Encode::decode_utf8( $cgi->param( 'realname' ) );

			unless( defined $description  &&  defined $realname ) {
				$panel->add_error( gettext('CGI Error !') );
			} elsif( $description =~ /^\s*$/ ) {
				$panel->add_error( gettext('You must enter a description') );
			} elsif( $realname =~ /^\s*$/ ) {
				$panel->add_error( gettext('You must enter a full name') );
			} elsif( substr($group->get_groupname,0,1) ne lc substr($realname,0,1) ) {
				$panel->add_error( gettext('The first letter of groupname and full name must be the same') );
			} else {
				$group->set_description($description);
				$group->set_realname($realname);
				if($group->commit < 0) {
					$panel->add_error( gettext('An error occured while updating the project') );
				} else {
					$panel->add_info( gettext('Group updated') );
				}
			}
		}
	} elsif( defined( $cgi->param( 'remove_user_submit' ) ) ) {
		# User removal
		my $uid = $cgi->param( 'uid' );
		unless( defined $uid  &&  $uid =~ /^\d+$/ ) {
			$panel->add_error( gettext('CGI Error !') );
		} else {
			unless( $uid == $user->get_uid || $user->can_modify( $group ) )  {
				$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );	
			} elsif( $uid == $group->get_owner_uid ) {
				$panel->add_error( gettext('You cannot remove the owner of the group') );
			} elsif( $group->remove_user($uid) ) {
				$panel->add_info( gettext('This user will be removed from this group as soon as possible') );
			} else {
				$panel->add_error( gettext('Unable to remove user from group') );
			}
		}
	} elsif( defined( $cgi->param( 'add_user_submit' ) ) ) {
		unless( $user->can_modify( $group ) ) {
			$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		} else {
			my $username = $cgi->param( 'username' );
			unless( defined $username ) {
				$panel->add_error( gettext('CGI Error !') );
			} elsif( $username =~ /^\s*$/ ) {
				$template->param( ADD_USER_MSG_CLASS => 'error' );
				$template->param( ADD_USER_MSG => gettext('You must enter an username') );
			} else {
				# First, we try to get an user with the *exact* name
				my $new_user = Vhffs::User::get_by_username( $vhffs, $username);
				if(defined $new_user) {
					# Fine, user exists, let's add it
					if( $group->add_user( $new_user->get_uid ) ) {
						$template->param( ADD_USER_MSG_CLASS => 'info' );
						$template->param( ADD_USER_MSG => gettext('User will be added as soon as possible') );
					} else {
						$template->param( ADD_USER_MSG_CLASS => 'error' );
						$template->param( ADD_USER_MSG => gettext('Unable to add user, he might already be in the group (waiting for addition or deletion)') );
					}
				} else {
					# User not found with exact match,let's search
					my $users = Vhffs::Panel::User::search( $vhffs , $username );
					unless( @{$users} ) {
						$template->param( ADD_USER_MSG_CLASS => 'error' );
						$template->param( ADD_USER_MSG => gettext('User not found') );
					} else {
						# Let's make a nice table
						my $subtemplate = new HTML::Template( filename => $templatedir.'/panel/group/list_user.tmpl', global_vars => 1, die_on_bad_params => 0 );

						$subtemplate->param( USERS => $users );
						$subtemplate->param( TEXT_ADD => gettext('Add') );
						$template->param( ADD_USER_MSG_CLASS => 'info' );
						$template->param( ADD_USER_MSG => gettext('Many users matched your query. Please choose between them') );
						$template->param( USERS_LIST => $subtemplate->output );
					}
				}
			}
		}
	} elsif( defined( $cgi->param('add_user_list_submit') ) ) {
		unless( $user->can_modify( $group ) ) {
			$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		} else {
			my $uid = $cgi->param( 'uid' );
			unless( defined $uid  &&  $uid =~ /^\d+$/ ) {
				$panel->add_error( gettext('CGI Error !') );
			} else {
				if( $group->add_user( $uid ) ) {
					$template->param( ADD_USER_MSG_CLASS => 'info' );
					$template->param( ADD_USER_MSG => gettext('User will be added as soon as possible') );
				} else {
					$template->param( ADD_USER_MSG_CLASS => 'error' );
					$template->param( ADD_USER_MSG => gettext('Unable to add user, he might already be in the group (waiting for addition or deletion)') );
				} 
			}
		}
	} elsif( defined( $cgi->param('contact_email_submit') ) ) {
		unless( $vhffs->get_config->get_service_availability('mailgroup')  &&  $user->can_modify( $group ) ) {
			$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		} else {
			my $forward = $cgi->param( 'contact_email' );
			unless( defined $forward  &&  ( $forward eq ''  ||  Vhffs::Functions::valid_mail( $forward ) )  ) {
				$panel->add_error( gettext('The email you entered fails syntax check') );
			} else {
				my $mg = init Vhffs::Services::MailGroup( $vhffs , $group );
				if( defined $mg )
				{
					if( $forward eq '' )  {
						$mg->delforward( $forward );
						$panel->add_info( gettext('Forward deleted') );
					} else {
						$mg->addforward( $forward );
						$panel->add_info( gettext('Forward added') );
					}
				}
			}
		}
	} elsif( defined( $cgi->param('update_quota_submit')) ) {
        update_quota();
    } elsif( defined( $cgi->param('add_tag_submit') ) ) {
    	add_tag();
    } elsif( defined( $cgi->param('delete_tag_submit') ) ) {
    	delete_tag();
    } elsif( defined( $cgi->param('request_tag_submit') ) ) {
    	request_tag();
    } elsif( defined( $cgi->param('cancel_tag_request_submit') ) ) {
    	cancel_request();
    }


	$panel->set_title( gettext('Project Preferences') );

	$template->param( TEXT_QUOTA => gettext("If you want more disk space for your project, you must fill a form in the bug report section, in the menu. Don't forget to mention the name of the group.") );
	$template->param( TEXT_PROJECTNAME => $group->get_groupname );
	$template->param( TEXT_OWNER => gettext("Project Owner") );
	$template->param( VALUE_OWNER => $group->get_owner_username );
	$template->param( TEXT_DESCRIPTION => gettext("Project Description") );
	$template->param( VALUE_DESCRIPTION => $group->get_description);
	$template->param( TEXT_REALNAME => gettext('Project full name') );
	$template->param( VALUE_REALNAME => $group->get_realname);
	$template->param( TEXT_MODIFY => gettext("Modify") );
	$template->param( TEXT_DELETE_PROJECT => gettext("Delete this project") );
	$template->param( TEXT_BEFORE_DELETE => gettext("This action is non-reversible. All services associated to this project will be DESTROYED.") );
	$template->param( ASK_DELETE_PROJECT => gettext("Are you SURE you want DELETE this project ?") );
	$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 => $group->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 $mg = init Vhffs::Services::MailGroup( $vhffs , $group );
	if( defined $mg )
	{
		$template->param( CONTACT_EMAIL_TITLE => gettext('Project contact') );
		$template->param( CONTACT_EMAIL_TEXT => sprintf( gettext('We offer you the possibility to forward emails from %s@%s.') , $group->get_groupname , $mg->{config}->{domain} ) );
		$template->param( CONTACT_EMAIL => $group->get_groupname.'@'.$mg->{config}->{domain} );
		$template->param( CONTACT_EMAIL_MODIFY => gettext('Modify') );
		$template->param( CONTACT_EMAIL_FORWARD => $mg->getforward );

		if( defined ( my $url = $mg->{config}->{'url_doc'} ) )  {
			$template->param( HELP_TEXT => gettext('Help') );
			$template->param( HELP_URL => $url );
		}
	}
	
	$template->param( TEXT_USERNAME => gettext("Username") );
	$template->param( TEXT_JOIN_GROUP => gettext("Add a user in this group") );
	$template->param( TEXT_SEND => gettext('Add') );

	if( $panel->use_groups_avatars )  {
		my $tavatar = new HTML::Template( filename => $templatedir.'/panel/group/prefs_avatar.tmpl', global_vars => 1 );		
		$tavatar->param( SEND_AVATAR => gettext('Update') );
		$tavatar->param( TEXT_AVATAR => gettext('Logo') );
		$tavatar->param( EXPLAIN_AVATAR => gettext('The avatar is an image to describe the group') );
		$tavatar->param( CURRENT_AVATAR => gettext('Current avatar') );
		$tavatar->param( UPDATE_AVATAR => gettext('Update avatar') );
		$tavatar->param( VALUE_OID => $group->get_oid);
		$template->param( AVATAR => $tavatar->output );
	}
	
	$template->param( USERS => Vhffs::Panel::Group::getall_users( $vhffs , $group->get_gid ) );
	$template->param( REMOVE_USER_TEXT => gettext( 'Remove' ) );
	$template->param( NO_USER_TEXT => gettext( 'No user for this group' ) );
	$template->param( USERS_TEXT => gettext( 'Users' ) );
	$template->param( CURRENT_USERS => gettext( 'All users in this group' ) );

    if($user->is_admin) {
        $template->param( ADMIN => 1 );
        my $adminpart = Vhffs::Panel::Object::admin_part( $panel, $group );
        $template->param( ADMIN_PART => $adminpart->output ) if( defined $adminpart );
        $template->param( QUOTA => $group->get_quota );
        $template->param( USED_QUOTA => $group->get_quota_used );
    }
    
    fill_tags();
}

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

sub update_quota {
    my $quota = $cgi->param('new_quota');
    unless(defined $quota && $quota =~ /^\d+$/) {
        $panel->add_error( gettext('Invalid quota') );
        return;
    }

    unless($user->is_admin()) {
        $panel->add_error( gettext('Only administrators are allowed to do this') );
        return;
    }

    $group->set_quota($quota);

    if($group->commit < 0) {
        $panel->add_error( gettext('Unable to apply modifications, please try again later') );
    } else {
        $panel->add_info( gettext('Group updated, please wait while quota is updated on filesystem') );
    }
}

sub fill_tags {
	my $visibility = ($user->is_admin() ? Vhffs::Constants::TAG_VISIBILITY_ADMINS :
				($user->is_moderator() ? Vhffs::Constants::TAG_VISIBILITY_MODERATORS :
					Vhffs::Constants::TAG_VISIBILITY_PUBLIC) ); 
	my $categories =
		Vhffs::Tag::Category::get_all($vhffs, $visibility);
	foreach my $c (@{$categories}) {
		$c->{tags} = Vhffs::Tag::get_by_category_id($vhffs, $c->{category_id});
	}
	$template->param( CATEGORIES => $categories );
	
	$template->param( CURRENT_TAGS => $group->get_tags($visibility) );
	
	$template->param( TAG_REQUESTS => $group->get_tag_requests() );
}

sub add_tag {
	unless( $user->can_modify( $group ) || $user->is_moderator) {
		$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		return 0;
	}
	
	my $tag_id = $cgi->param('tag_id');
	
	unless(defined $tag_id) {
		$panel->add_error( gettext('CGI error') );
		return 0;
	}
	
	my $tag = Vhffs::Tag::get_by_tag_id($vhffs, $tag_id);
	
	unless(defined $tag) {
		$panel->add_error( gettext('Tag not found') );
		return 0;
	}
	
	if( ($tag->{visibility} >= Vhffs::Constants::TAG_VISIBILITY_ADMINS && !$user->is_admin()) ||
		($tag->{visibility} >= Vhffs::Constants::TAG_VISIBILITY_MODERATORS && !$user->is_moderator())) {
		$panel->add_error( gettext('You don\'t have enough privileges to add this tag') );
		return 0;
	}
	
	if($group->add_tag($tag, $user)) {
		$panel->add_info( gettext('Tag added') );
	} else {
		$panel->add_error( gettext('Unable to add tag, check it was not already added to your project') );
	}
}

sub delete_tag {
	unless( $user->can_modify( $group ) || $user->is_moderator) {
		$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		return 0;
	}
	
	my $tag_id = $cgi->param('tag_id');
	
	unless(defined $tag_id) {
		$panel->add_error( gettext('CGI error') );
		return 0;
	}
	
	my $tag = Vhffs::Tag::get_by_tag_id($vhffs, $tag_id);
	
	unless(defined $tag) {
		$panel->add_error( gettext('Tag not found') );
		return 0;
	}
	
	if( ($tag->{visibility} >= Vhffs::Constants::TAG_VISIBILITY_ADMINS && !$user->is_admin()) ||
		($tag->{visibility} >= Vhffs::Constants::TAG_VISIBILITY_MODERATORS && !$user->is_moderator())) {
		$panel->add_error( gettext('You don\'t have enough privileges to delete this tag') );
		return 0;
	}
	
	if($group->delete_tag($tag, $user)) {
		$panel->add_info( gettext('Tag deleted') );
	} else {
		$panel->add_error( gettext('Unable to delete tag') );
	}
}

sub request_tag {
	unless( $user->can_modify( $group ) ) {
		$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		return 0;
	}
	
	my $category_label = $cgi->param('category');
	my $tag_label = $cgi->param('tag');
	
	unless(defined $category_label && defined $tag_label) {
		$panel->add_error( gettext('CGI error') );
		return 0;
	}
	
	if($category_label =~ /^\s*$/) {
		$panel->add_error( gettext('Category can\'t be empty') );
		return 0;
	}
	
	if($tag_label =~ /^\s*$/) {
		$panel->add_error( gettext('Tag name can\'t be empty') );
		return 0;
	}
	
	unless( defined(Vhffs::Tag::Request::create($vhffs, $category_label, $tag_label, $user, $group) ) ) {
		$panel->add_error( gettext('An error occured while saving your request') );
		return;
	}
	
	$panel->add_info( gettext('Tag request saved, please wait while a moderator approve it') );
	
}

sub cancel_request {
	unless( $user->can_modify( $group ) ) {
		$panel->add_error( gettext( 'You\'re not allowed to do this (ACL rights)' ) );
		return 0;
	}
	
	my $request_id = $cgi->param('request_id');
	
	my $request = Vhffs::Tag::Request::get_by_request_id($vhffs, $request_id);
	
	unless(defined $request) {
		$panel->add_error( gettext('Request not found') );
		return 0;
	}
	
	if($request->{tagged_id} != $group->get_oid()) {
		$panel->add_error( gettext('You can only delete requests attached to your group') );
		return 0;
	}
	
	$request->delete();
	
	$panel->add_info( gettext('Request canceled') );
	return 1;
}
