#!/usr/bin/perl -w
#
#  This script imports and updates Group members into CGPro.
#
#  The first line of the import file is a comment and it is ignored by the script.
#  The second line is the Group name, optionally with the domain part, then
#  optionally the tabulation character and the Group's real name. 
#  The other lines are Group member names, one per line. If the name
#  is prefixed with '-' then that member will be deleted from the Group,
#  otherwise it will be added to the Group. Duplicates are removed.
#
#  Example:
#  ---------
#  a comment
#  my_group@domain.com<TAB>My Group Real Name
#  user1
#  user2@exteranl.domain.com
#  -user3
#  ---------
#
#  Usage: ImportGroup.pl login:password@host InputFile.txt
#  If 'login:' is ommited then 'postmaster' login is assumed.
#  If 'host' is ommited then '127.0.0.1' is used.
#  The '@' in login should be replaced with '%', e.g. user%sub-domain.com 
#
#
#  Please mail your reports and suggestions to <support@stalker.com>
#
#

use strict;
use CLI;                  # make sure the CLI.pm is in the current directory

# Check the program's arguments
if(@ARGV<2 || !($ARGV[0] =~ /(.*)\@(.*)/ ) ) {
  print "Usage: ImportGroup.pl [login:]password\@host InputFile.txt\n";
  exit;
}

my $Login='postmaster';
my $Password=$1;
my $CGServerAddress=$2 || '127.0.0.1';

if( $ARGV[0] =~ /(.*):(.*)\@/) {
  $Login=$1; $Password=$2;
}

open(FILE,$ARGV[1]) || die "Can't open $ARGV[1]: $!\n";


# Open TCP connection to given address port 106 (PWD, or CGPro CLI).
# Submit username and password. If login fail, the program will stop.

print "Connecting to CGPro at $CGServerAddress as $Login\n";
my $cli = new CGP::CLI( { PeerAddr => $CGServerAddress,
                          PeerPort => 106,
                          login    => $Login,
                          password => $Password } )
   || die "Can't login to CGPro: ".$CGP::ERR_STRING."\n";

<FILE>; # stip the 1st line with possible UTF-8 byte order marker
my $input=<FILE>;
chomp($input);
my @params=split(/\t/,$input);
my $groupName=$params[0];
my $groupRealName=$params[1] || 'no real name';

print "Group: $groupName ($groupRealName)\n";


my $groupDomain='';
if($groupName =~ /\@(.*)/) {
  $groupDomain=$1;
}

my $groupSettings=$cli->GetGroup($groupName);

unless($groupSettings) {
  $cli->CreateGroup($groupName) ||
          die "Error: ".$cli->getErrMessage.", quitting";
  $groupSettings=$cli->GetGroup($groupName) ||
          die "Error: ".$cli->getErrMessage.", quitting";        
}

@$groupSettings{RealName}=$groupRealName if($groupRealName ne 'no real name');

my $membersList=@$groupSettings{Members};
my %newMembersList;
foreach(@$membersList) {
  if(/(.*)\@(.*)/) {
    if($2 =~ /^$groupDomain$/i) {     
      $_=$1;
    }
  }
  $newMembersList{$_}=1;
}

while(<FILE>) {                                       # read a line from the input file
  chomp($_);                                      # remove the \n from the line
  my $name=$_;

  next if(!defined $name || $name eq '');         # skip if it was empty line
  if($name =~ /(.*)\@(.*)/) {
    my $unqName=$1;
    if($2 =~ /^$groupDomain$/i) {
      $name=$unqName;
    }
  }

  if($name =~ /^\-(.*)/) {
    if(exists $newMembersList{$1}) {
      print qq/deleting "$1"\n/; 
      delete $newMembersList{$1};    
    } else {
      print qq/"$name": can't delete because it does not exist\n/;    
    }   
  } else {
    unless(exists $newMembersList{$name}) {
      my $fqdnName=($name =~ /\@/ || $groupDomain eq '') ? $name : $name .'@'.$groupDomain;
      unless($cli->Route($fqdnName)) {
        print qq/"$name": /.$cli->getErrMessage."\n";
      } else {
        print qq/adding "$name"\n/;
        $newMembersList{$name}=1;
      }  
    } else {
      print qq/"$name" can't add because it already exists\n/;  
    }
  }
}
close(FILE);
my @newMembersList=sort keys(%newMembersList);
@$groupSettings{Members}= \@newMembersList;

$cli->SetGroup($groupName,$groupSettings) ||
          die "Error: ".$cli->getErrMessage.", quitting";

$cli->Logout;
print "The group naw has ".@newMembersList." member(s)\n"; 

__END__;

