# FILE: fcn-grp.pl
# DESCRIPTION: Group Manipulation Functions (groups.txt)
#-------------------------------------------------------------------------------
# DISCUS COPYRIGHT NOTICE
#
# Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
#    http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------

use strict;
use vars qw($GLOBAL_OPTIONS $DCONF $PARAMS);

###
### check_group_authorization
###
### Checks to see if $moderator is authorized to edit $group
###

sub check_group_authorization {
	my ($moderator, $group, $file_in) = @_;
	return 1 if $moderator eq $DCONF->{superuser};
	if (! defined $file_in) {
		$file_in = read_group_file();
	}
	return $file_in->{by_mod}->{$moderator}->{$group};
}

###
### read_group_file
###
### Low-level reading of the groups.txt file
###

sub read_group_file {
	my ($no_lock) = @_;
	my $file = $no_lock == 1 ? readfile("$DCONF->{admin_dir}/groups.txt", "read_group_file", { no_lock => 1, no_unlock => 1, zero_ok => 1 }) : readfile("$DCONF->{admin_dir}/groups.txt", "read_group_file", { zero_ok => 1 });
	undef my $result;
	foreach my $line (@{ $file }) {
		chomp $line;
		my ($grp, $mods) = split(/:/, $line);
		next if $grp eq "#";
		next if $grp !~ m|\S|;
		my @mods = split(/,/, $mods);
		push (@{ $result->{group_list} }, $grp);
		foreach my $mod (@mods) {
			$result->{by_mod}->{$mod}->{$grp} = 1;
			$result->{by_grp}->{$grp}->{$mod} = 1;
		}
	}
	return $result;
}

###
### write_group_file
###
### Low-level writing of the groups.txt file based on a list of "actions"
###

sub write_group_file {
	my ($actions) = @_;
	my @newfile = ();
	my @newgroups = ();
	undef my $classify;
	foreach my $action (@{ $actions }) {
		my ($gr, $a, $m) = ($action->{group}, $action->{action}, $action->{moderator});
		foreach my $g (split(/,/, $gr)) {
			if ($a eq "add_group") {
				push (@newgroups, $g);
			} elsif ($a eq "del_group") {
				$classify->{$g}->{del} = 1;
			} elsif ($a eq "set_equal") {
				$classify->{$g}->{modequals} = $m;
			} else {
				foreach my $md (split(/,/, $m)) {
					if ($a eq "add_mod") {
						$classify->{$g}->{modadd}->{$md} = 1;
					} elsif ($a eq "del_mod") {
						$classify->{$g}->{moddel}->{$md} = 1;
					}
				}
			}
		}
	}
	my $file = readfile("$DCONF->{admin_dir}/groups.txt", "write_group_file", { no_unlock => 1, zero_ok => 1 });
	my $c = 0;
	undef my $groups;
	foreach my $line (@{ $file }) {
		my $line_manip = $line; chomp $line_manip;
		my ($grp, $mods) = split(/:/, $line_manip);
		if ($grp eq "#") {
			push (@newfile, $line); next;
		}
		if ($grp !~ m|\S|) {
			next;
		}
		if (defined $classify->{$grp}->{modequals}) {
			push (@newfile, "$grp:$classify->{$grp}->{modequals}\n");
			next;
		}
		if ($classify->{$grp}->{del}) {
			$c += 1; next;
		}
		my @mods = split(/,/, $mods);
		undef my @modsnew;
		foreach my $m (@mods) {
			next if $classify->{$grp}->{moddel}->{$m};
			next if $classify->{$grp}->{modadd}->{$m};
			next if $classify->{"*"}->{moddel}->{$m};
			push (@modsnew, $m);
		}
		foreach my $k (keys(%{ $classify->{$grp}->{modadd} })) {
			push (@modsnew, $k);
		}
		$mods = join(",", sort @modsnew);
		$line_manip = join(":", $grp, $mods);
		$line_manip .= "\n";
		push (@newfile, $line_manip);
		$groups->{$grp} = 1;
	}
	foreach my $i (@newgroups) {
		if (! $groups->{$i} ) {
			push (@newfile, "$i:$DCONF->{superuser}\n");
			$c += 1;
		}
	}
	writefile("$DCONF->{admin_dir}/groups.txt", \@newfile, "write_group_file", { no_lock => 1, zero_ok => 1 });
	return $c;
}

1;
