#!/usr/bin/perl -w
# 
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1
# 
# The contents of this file are subject to the Mozilla Public License
# Version 1.1 ("License"); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://www.zimbra.com/license
# 
# Software distributed under the License is distributed on an "AS IS"
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
# the License for the specific language governing rights and limitations
# under the License.
# 
# The Original Code is: Zimbra Collaboration Suite Server.
# 
# The Initial Developer of the Original Code is Zimbra, Inc.
# Portions created by Zimbra are Copyright (C) 2006 Zimbra, Inc.
# All Rights Reserved.
# 
# Contributor(s):
# 
# ***** END LICENSE BLOCK *****
# 

use strict;
use English '-no_match_vars';
use FileHandle;
use Time::Local;
use POSIX qw(strftime);

$FORMAT_LINES_PER_PAGE = 1000000;
$FORMAT_FORMFEED = "\n";

my $ldappass = `/opt/zimbra/bin/zmlocalconfig -s -m nokey zimbra_ldap_password`;
my $ldapdn  = `/opt/zimbra/bin/zmlocalconfig -s -m nokey zimbra_ldap_userdn`;
my $ldaphost  = `/opt/zimbra/bin/zmlocalconfig -s -m nokey ldap_host`;
chop($ldappass);
chop($ldapdn);
chop($ldaphost);

if ($ldaphost eq '') {
  $ldaphost = "localhost";
}

my $ldapsearch = "/opt/zimbra/openldap/bin/ldapsearch";
my $ldapquery = "(&(objectclass=zimbraAccount)(!(objectclass=zimbraCalendarResource)))";
my $ldapargs = "-x -h $ldaphost -w $ldappass -D $ldapdn";
my $ldapattrs =  "zimbraMailDeliveryAddress zimbraAccountStatus createTimestamp zimbraLastLogonTimestamp";

my $search = "$ldapsearch $ldapargs '$ldapquery' $ldapattrs";

open(LDAPSEARCH, "$search |") || die "can't open ldapsearch: $!\n";

my $domains = {};

while (<LDAPSEARCH>) {
	my $entry = {};
	if (/^#/) {
		while(<LDAPSEARCH>) {
			chomp;
			last if $_ eq '';
			if (/^(\w+):\s+(.*)$/) {
				$entry->{$1} = $2;
			}
		}
		if ($entry->{'zimbraMailDeliveryAddress'}) {
			my ($local, $domain) = split /@/,$entry->{'zimbraMailDeliveryAddress'};
			my $dd = $domains->{$domain};
			if (!$dd) { $dd = $domains->{$domain} = { stats => {}, accounts => {}}; }
			$dd->{'stats'}->{'total'}++;
			$dd->{'stats'}->{$entry->{'zimbraAccountStatus'}}++;
			$dd->{'accounts'}->{$local} = $entry;
		}
	}
}

my ($domainName, $domainNameHeader, $name, $status, $created, $logon);

format ACCOUNT_TOP = 
           account                          status             created       last logon
------------------------------------   -----------     ---------------  ---------------  
.

format ACCOUNT = 
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<   @>>>>>>>>>>     @>>>>>>>>>>>>>>  @>>>>>>>>>>>>>>
$name, $status, $created, $logon
.

format_name     STDOUT "ACCOUNT";
format_top_name STDOUT "ACCOUNT_TOP";

foreach $domainName (sort keys %$domains) {

	my $dd = $domains->{$domainName};
	my $accounts = $dd->{'accounts'};

	$domainNameHeader = "domain $domainName";
	foreach my $account (sort keys %$accounts) {
		my $entry = $accounts->{$account};

		$name = "$account\@$domainName";
		$status = $entry->{'zimbraAccountStatus'};
		$created = $entry->{'createTimestamp'};
		$logon = $entry->{'zimbraLastLogonTimestamp'} || 'never';

		if ($created =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/) {
			my $time = timegm($6, $5, $4, $3, $2-1, $1);
			$created = strftime("%D %H:%M", localtime($time));
		}
		if ($logon =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z/) {
			my $time = timegm($6, $5, $4, $3, $2-1, $1);
			$logon = strftime("%D %H:%M", localtime($time));
		}


	write;
	}
	$FORMAT_LINES_LEFT = 0;
}

$FORMAT_LINES_LEFT = 0;


my ($numActive, $numClosed, $numLocked, $numMaint, $numTotal);


format DOMAIN_TOP =
                                 domain summary

    domain                  active    closed    locked    maintenance     total
-----------------------   --------  --------  --------  -------------  --------
.

format DOMAIN =
@<<<<<<<<<<<<<<<<<<<<<<   @>>>>>>>  @>>>>>>>  @>>>>>>>  @>>>>>>>>>>>>  @>>>>>>>
$domainName, $numActive, $numClosed, $numLocked, $numMaint, $numTotal
.

format_top_name STDOUT "DOMAIN_TOP";
format_name     STDOUT "DOMAIN";


foreach $domainName (sort keys %$domains) {
	my $dd = $domains->{$domainName};
	my $stats = $dd->{'stats'};
	$numActive = $stats->{'active'} || 0;
	$numClosed = $stats->{'closed'} || 0;
	$numLocked = $stats->{'locked'} || 0;
	$numMaint  = $stats->{'maintenance'} || 0;
	$numTotal  = $stats->{'total'} || 0;
	write;
}

