#!/usr/local/bin/perl
# 
# $Header: oidclient.pl 30-aug-2005.22:39:19 fsalim Exp $
#
# oidclient.pl
# 
# Copyright (c) 2003, 2005, Oracle. All rights reserved.  
#
#    NAME
#      oidclient.pl - <one-line expansion of the name>
#
#    DESCRIPTION
#      <short description of component this file declares/defines>
#
#    NOTES
#      <other useful comments, qualifications, etc.>
#
#    MODIFIED   (MM/DD/YY)
#    fsalim      08/30/05 - To comment error_desc for bug_4577640 
#    fsalim      07/31/05 - To fix the bug 4527500 related to ldap compare 
#    fsalim      07/26/05 - Fix for bug 4503753 
#    mbisarya    12/10/04 - changes to be made for retryinterval and 
#                           numretries 
#    tjaiswal    11/12/04 - tjaiswal_test_type_impl
#    tjaiswal    02/12/04 - Bug 3432641 
#    abhavnan    11/13/03 - fix env var requirements for ldap utils:bug 3251925
#    gmulchan    07/30/03 - gmulchan_ocsv1_main_merge
#    tjaiswal    04/20/03 - Creation
# 
#use strict;
use Time::HiRes;
use Getopt::Long; # set up to accept user input
use Net::LDAP;
use ParseStdin;
require "emd_common.pl";

my $OSNAME = $^O;

ParseStdin::initStdin();
my $ldap_password   = ParseStdin::getParameter("password");

GetOptions(\%cmdLine,
            "BeaconName=s",
            "TxnName=s",
			"retryinterval=i",
            "ldap_port=i",
            "ldap_address=s",
            "ldap_user_name=s",
            "numretries=i",
            "ldap_filter=s",
            "ldap_base=s",
            "ldap_attrname=s",
            "ldap_attrvalue=s",
			"ldap_timeout=s");

my $beaconName      = $cmdLine{"BeaconName"};
my $txnName         = $cmdLine{"TxnName"};
my $ldap_host       = $cmdLine{"ldap_address"};
my $ldap_port       = $cmdLine{"ldap_port"};
my $ldap_username   = $cmdLine{"ldap_user_name"};
my $retryinterval   = $cmdLine{"retryinterval"};
my $ldap_fail_count = $cmdLine{"numretries"};
my $filter          = $cmdLine{"ldap_filter"};
my $base            = $cmdLine{"ldap_base"};
my $attrName        = $cmdLine{"ldap_attrname"};
my $attrValue       = $cmdLine{"ldap_attrvalue"};
my $ldap_timeout	= $cmdLine{"ldap_timeout"};


# metrics
######
$status = 1;			# be optimistic
$msgsrch_time = 0;
$addrsrch_time = 0;
$basesrch_time = 0;
$compare_time = 0;
$check_ldapcompare = 0;
$combinedErrTxt = "";
####


#print "\nMessaging Search:\n";
$filterBaseSrch = "$filter*";
#print "The filter is $filter\n";
$filter = "($filter)";
#print "The filter is $filter\n";
$filterBaseSrch = "($filterBaseSrch)";

my $ldap;

do {
	if ( $fail_count > 0)
	{
		sleep $retryinterval;
	}
	
	$connect_time = getLDAPConnection($ldap_host, $ldap_port, $ldap_username,$ldap_password, $ldap_timeout);
	$fail_count++;
}while ($fail_count < $ldap_fail_count && $status == 0);

if ($connect_time != 0)
{
	$msgsrch_time = doLdapOperation ($ldap_host, $ldap_port, $filter, "sub","search", $ldap_username,$ldap_password,$base);

	#print "\nAddressing Search:\n";
	$addrsrch_time = doLdapOperation ($ldap_host, $ldap_port, $filterBaseSrch, "sub","search", $ldap_username,$ldap_password,$base);

	#print "\nBase Search:\n";
	$basesrch_time = doLdapOperation ($ldap_host, $ldap_port, "(objectClass=*)", "base","search", $ldap_username,$ldap_password,$base);

	#print "\nCompare:\n";
	$compare_time = doLdapOperation ($ldap_host, $ldap_port, "", "","compare", $ldap_username,$ldap_password,$base,$attrName,$attrValue);

	# Important : Convert to milliseconds.
	$connect_time = toMilliSec($connect_time);
	$msgsrch_time = toMilliSec($msgsrch_time) ;
	$addrsrch_time = toMilliSec($addrsrch_time) ;
	$basesrch_time = toMilliSec($basesrch_time) ;
	$compare_time = toMilliSec($compare_time) ;

}
else
{
	$combinedErrTxt = $errtxt;
}
#print "Messaging Search Time = $msgsrch_time\n";
#print "Addressing Search Time = $addrsrch_time\n";
#print "Base Search Time = $basesrch_time\n";

printf("em_result=$txnName|$beaconName|$status|$connect_time|$msgsrch_time|$addrsrch_time|$basesrch_time|$compare_time|$combinedErrTxt\n");

sub getLDAPConnection
{
	my ($machineName, $portNumber, $username, $password, $ldap_timeout) = @_;
	$start_time = Time::HiRes::time();
	
	if ($ldap_timeout) {
		$ldap = Net::LDAP->new($machineName,port=>$portNumber, timeout=>$ldap_timeout);
	}
	else {
		$ldap = Net::LDAP->new($machineName,port=>$portNumber);
	}
	print ("The ldap is $ldap\n");
	if ( not $ldap ) {
		$errtxt = "Could not connect to ldap server, please check machine name and port number";
		$status = 0;
		#print ("em_result=$txnName|$beaconName|$status|$errtxt\n");
		#exit 0;
		return 0;
	}
	$bindmesg = $ldap->bind($username,password=>$password);
	$bindCode = $bindmesg->code();
	print "The bindCode is $bindCode\n";
	if ($bindCode != 0) {
		#$errmsg = $bindmesg->error();
		$errtxt = $bindmesg->error_text();
		#$errdesc = $bindmesg->error_desc();
		#print ("The errmsg is $errmsg\n");
		#print ("The errtxt is $errtxt\n");
		#print ("The errdesc is $errdesc\n");
		$status = 0;
		#print ("em_result=$txnName|$beaconName|$status|$errtxt\n");
		#print "em_result=$status";
		#exit 0;
		return 0;
	}
	return (Time::HiRes::time() - $start_time);
}

sub releaseLDAPConnection 
{
	ldap->unbind();
}

sub doLdapOperation
{
	my ($machineName,$portNumber,$filter,$scopeOfOper,$operType, $username,$password,$base,$attrName, $attrValue) = @_;
	
	for my $t (($machineName,$portNumber,$filter,$scopeOfOper,$operType, $username,$password,$base,$attrName, $attrValue)) {
		#print "$t\n";
	}
	
	$start_time = Time::HiRes::time();
	
	
	print "The operation type is $operType\n";
	if ($operType =~ /^search$/) {
		#$filter = "(cn=Person One11)";	
		#$scopeOfOper = "sub";
		#$base = "c=US";
		if ($scopeOfOper == "sub") {
			print "before searching\n";
			$searchMsg = $ldap->search(filter=>$filter, base=>$base, scope=>$scopeOfOper);
		}
		else {
			$searchMsg = $ldap->search(filter=>$filter,base=>$base, scope=>$scopeOfOper);
		}
		$retcode = $searchMsg->code();
		print ("The return code is $retcode\n");
		if ($retcode != 0) {
			$errmsg = $searchMsg->error();
			$errtxt = $searchMsg->error_text();
			#$errdesc = $searchMsg->error_desc();
			$status = 0;
			#print ("em_result=$txnName|$beaconName|$status|$errtxt\n");
			#exit 0;
		}
		$numEntries = $searchMsg->count;
		print "The num entries returned by search is $numEntries\n";
		if ($numEntries == 0) {
			
			$combinedErrTxt = "$combinedErrTxt The search operation with base: $base and filter: $filter did not return any results.";
		}
	}
	else {
		#$attrName = "treet";
		#$attrValue = "24  Dougan Stree";
		
		#EMD_PERL_DEBUG("before comparing $attrName and $attrValue\n");
		$compareMsg = $ldap->compare(dn=>$base,attr=>$attrName,value=>$attrValue);
		$retCode = $compareMsg->code();
		print "The result of comparing is $retCode\n";
		if ($retCode != 6) {
			$status = 0;
			$errmsg = $compareMsg->error();
			$errtxt = $compareMsg->error_text();
			#$errdesc = $compareMsg->error_desc();
			$errtxt = "Compare operation failed, $errtxt";
			$combinedErrTxt = "$combinedErrTxt The compare operation with attribute name: $attrName and attribute value: $attrValue failed with message: $errtxt";
			
		}
	}
	#$ldap->unbind();
	return (Time::HiRes::time() - $start_time);
}


sub toMilliSec 
{
    my ( $time_in_sec) = @_;
    return $time_in_sec * 1000;
}

