package EventStaffSystem;
use strict;

#@api MyPoint
##########################Change Log
#@change_date Tue 21 July 2015
#@change_desc Initial API Created
#@change_auth Danie van der Walt

use Apache2::RequestRec ();
use Apache2::Connection ();
use Apache2::RequestIO ();
use Apache2::Const -compile => qw(OK);

use CGI;
use DBI; 
use Time::CTime;
use Time::HiRes;
use POSIX;
use XML::Simple;
use JSON;
use LWP;
use LWP::ConnCache;
use Data::Dumper;
use Log::Log4perl;
use Env;

##Pull in Libs
require '/var/www/EventStaffAPI/APILibs/GenericFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/DBVersions.pm';
require '/var/www/EventStaffAPI/APILibs/CronFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/AgencyFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/UserCategoryFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/UserEventFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/UserNotificationsFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/UserPaymentsFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/UserProfileFunctions.pm';
require '/var/www/EventStaffAPI/APILibs/UserFunctions.pm';

##########################################################################################################
# Globals
##########################################################################################################
$ENV{XML_SIMPLE_PREFERRED_PARSER} = "XML::LibXML::SAX::Parser";
#$ENV{XML_SIMPLE_PREFERRED_PARSER} = "XML::Parser";
my $gDEBUG=1;
my $gREMOTE_ADDR;

my $gMainPath = "";

my %GLOBALS;
our $CONFIGPATH="/var/www/EventStaffAPI/Config";
our $log_conf = "/var/www/EventStaffAPI/logConf";
#our $GLOBALFILEHANDLE;
our $GLOBALLOGGERHANDLE;

my $gdbhMain;
our $dsnMain= "";
our $userMain= "";
our $passwordMain= "";
our $query;
our $gResponseXml="";
our $gRequestType="";

##########################################################################################################
# System Related Globals
##########################################################################################################
my $LS = "/bin/ls";
my $SORT = "/usr/bin/sort";
my $WC = "/usr/bin/wc";
my $DATE = "/bin/date";
my $MKDIR = "/bin/mkdir";
my $MV = "/bin/mv";
my $RM = "/bin/rm";
my $TAIL = "/usr/bin/tail";
my $CP = "/bin/cp";
my $CAT = "/bin/cat";
my $SENDEMAIL = "/usr/bin/sendEmail";
my $HOSTNAME = "/bin/hostname";
my $HTML2PS = "/usr/local/sbin/html2ps";
my $GS = "/usr/bin/gs";
my $TOUCH = "/usr/bin/touch";
my $TIFFINFO = "/usr/bin/tiffinfo";
my $GREP = "/bin/grep";
my $DU = "/usr/bin/du";
my $FIND = "/usr/bin/find";
my $DIFF = "/usr/bin/diff";
my $CHMOD = "/bin/chmod";
my $ZIP = "/usr/bin/zip";
my $UNZIP = "/usr/bin/unzip";
my $NCFTPPUT = "/usr/bin/ncftpput";
my $NCFTPGET = "/usr/bin/ncftpget";

##########################################################################################################
# Main Handler Functions
##########################################################################################################
#-------------------------------------------------------------------------------------------------------
sub handler {
    my $r = shift;

    PackageMain("","");

    return Apache2::Const::OK;
}

#-------------------------------------------------------------------------------------------------------
sub PackageMain($$)
{
  my($info,$r_ip) = @_;
  my $ret;
  my $SySchk=0;
  my $receivedHash;
  my $receivedXML;
  my $XMLaction;
  my $call_type;

  $gREMOTE_ADDR = $r_ip;

  #LoadGlobals->new( \%GLOBALS );
  LoadGlobals();
  
  ##Get Logger Conf
  Log::Log4perl::init($log_conf);  
  $GLOBALLOGGERHANDLE = Log::Log4perl->get_logger();
  
  $query = new CGI;
  print $query->header('text/html');
  my $StartTime=Time::HiRes::time();

  
#     my $sth = $gdbhMain->prepare("START TRANSACTION");
#     $GLOBALLOGGERHANDLE->info("START TRANSACTION");
#     $sth->execute;
#     
  $receivedXML = read_request();
  if ($receivedXML eq (""))
  {
    $gResponseXml = My_GenericFunctions->return_error("Invalid XML please try again","");
  }
  else
  {
    $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");
    $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");
    $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");
    $GLOBALLOGGERHANDLE->info("".strftime("%Y%m%d%H%M%S",localtime(time))."");
    my $receivedXMLTmp = $receivedXML;
    $receivedXMLTmp =~ s/\n//ig;
    $GLOBALLOGGERHANDLE->info("$receivedXMLTmp");
    $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");

    $SySchk=0;
    eval
    {
      if(index(lc(substr($receivedXML,0,10)),"xml")>-1)
      {
        $gRequestType="XML";
        $receivedXML =~ s/\"/\'/ig;
        $receivedHash = XMLin($receivedXML,SuppressEmpty => undef) or $SySchk=1;
      }
      else
      {
        $gRequestType="JSON";
        $receivedHash = decode_json($receivedXML) or $SySchk=1;
      }
    };

    if ($@) {
      $gResponseXml = My_GenericFunctions->return_error("Invalid $gRequestType ($@)","");
      $GLOBALLOGGERHANDLE->info("\nInvalid $gRequestType ||$receivedXML||");
    }
    else
    {
      $XMLaction = lc($receivedHash->{api_action});
      ##Do MEMCACHE STUFF
      if($GLOBALS{"CACHE_response_$XMLaction"} ne "" && ($gResponseXml=My_GenericFunctions->CheckMemCacheResponse($receivedXML,$GLOBALS{"CACHE_response_$XMLaction"})) ne ""){ $call_type = "MEMCACHE"}
      else
      {
        $gdbhMain = DBI->connect($GLOBALS{DB_CONNECT_STRING},$GLOBALS{DB_USERNAME},$GLOBALS{DB_PASSWORD}) or $SySchk=1;
        if($SySchk==1)
        {
          $gResponseXml = My_GenericFunctions->return_error();
        }
        else
        {
      
          ##DBVersionCheck
          my $DBVersion = new My_DBVersions($gdbhMain,\%GLOBALS,$receivedXML);
          $DBVersion->check_db_version();
                    
          #$GLOBALLOGGERHANDLE->info(Dumper($query));
          #-------------------------------------------------------------------------------------------------------
          # Start Function If Check
          #-------------------------------------------------------------------------------------------------------
          if(substr($XMLaction,0,15) eq "user_functions_")
          {
            my $Functions = new My_UserFunctions($gdbhMain,\%GLOBALS);
            
            if($XMLaction eq "user_functions_get_agency_from_domain"){$gResponseXml = $Functions->user_functions_get_agency_from_domain($receivedHash);}
            elsif($XMLaction eq "user_functions_login"){$gResponseXml = $Functions->user_functions_login($receivedHash);}
            elsif($XMLaction eq "user_functions_forgot_password"){$gResponseXml = $Functions->user_functions_forgot_password($receivedHash);}            
            elsif($XMLaction eq "user_functions_validate_session"){$gResponseXml = $Functions->user_functions_validate_session($receivedHash);}
            elsif($XMLaction eq "user_functions_user_type_list"){$gResponseXml = $Functions->user_functions_user_type_list($receivedHash);}
            elsif($XMLaction eq "user_functions_agency_user_list"){$gResponseXml = $Functions->user_functions_agency_user_list($receivedHash);}
            elsif($XMLaction eq "user_functions_user_add"){$gResponseXml = $Functions->user_functions_user_add($receivedHash);}
            elsif($XMLaction eq "user_functions_user_list"){$gResponseXml = $Functions->user_functions_user_list($receivedHash);}
            elsif($XMLaction eq "user_functions_user_activate"){$gResponseXml = $Functions->user_functions_user_activate($receivedHash);}
						elsif($XMLaction eq "user_functions_user_delete"){$gResponseXml = $Functions->user_functions_user_delete($receivedHash);}
						elsif($XMLaction eq "user_functions_user_decline"){$gResponseXml = $Functions->user_functions_user_decline($receivedHash);}
						elsif($XMLaction eq "user_functions_user_event_requires_agency_approval"){$gResponseXml = $Functions->user_functions_user_event_requires_agency_approval($receivedHash);}
						elsif($XMLaction eq "user_functions_user_change_password"){$gResponseXml = $Functions->user_functions_user_change_password($receivedHash);}
						elsif($XMLaction eq "user_functions_user_category_to_accept"){$gResponseXml = $Functions->user_functions_user_category_to_accept($receivedHash);}
            
            
            else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
          }  
          elsif(substr($XMLaction,0,17) eq "agency_functions_")
          {
            my $Functions = new My_AgencyFunctions ($gdbhMain,\%GLOBALS);
                        
            if($XMLaction eq "agency_functions_agency_setting_types_list"){$gResponseXml = $Functions->agency_functions_agency_setting_types_list($receivedHash);}
            else
            {
  						my $User_Functions = new My_UserFunctions($gdbhMain,\%GLOBALS);
						  my ($tUSER_id,$tUSER_TYPE_value,$tAGENCY_value,$tAGENCY_id,$active) = $User_Functions->internal_validate_session($receivedHash);
						  if($tUSER_id==-1)
						  {
						    $gResponseXml = (My_GenericFunctions->return_error("Invalid Session_id.","warn"));
						  }
						  else
						  {	
  							$GLOBALS{tUSER_id}=$tUSER_id;
	  						$GLOBALS{tUSER_TYPE_value}=$tUSER_TYPE_value;
		  					$GLOBALS{tAGENCY_value}=$tAGENCY_value;
			  				$GLOBALS{tAGENCY_id}=$tAGENCY_id;
							
  							if(index($tAGENCY_value,"Agency")==-1)
	  						{
		  				    $gResponseXml = (My_GenericFunctions->return_error("No Permissions to Access This Function.","warn"));
			  				}
			  				else
			  				{            
    	            if($XMLaction eq "agency_functions_agency_settings_list"){$gResponseXml = $Functions->agency_functions_agency_settings_list($receivedHash);}
    	            elsif($XMLaction eq "agency_functions_agency_settings_edit"){$gResponseXml = $Functions->agency_functions_agency_settings_edit($receivedHash);}
	             
	                else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
	              }
	            }
            }                      
          }
          elsif(substr($XMLaction,0,23) eq "user_profile_functions_")
          {
            my $Functions = new My_UserProfileFunctions ($gdbhMain,\%GLOBALS);
                        
						if($XMLaction eq "user_profile_functions_user_profile_types_list"){$gResponseXml = $Functions->user_profile_functions_user_profile_types_list($receivedHash);}
						else
						{
                        
  						my $User_Functions = new My_UserFunctions($gdbhMain,\%GLOBALS);
						  my ($tUSER_id,$tUSER_TYPE_value,$tAGENCY_value,$tAGENCY_id,$active) = $User_Functions->internal_validate_session($receivedHash);
						  if($tUSER_id==-1)
						  {
						    $gResponseXml = (My_GenericFunctions->return_error("Invalid Session_id.","warn"));
						  }
						  else
						  {	
   		 					$GLOBALS{tUSER_id}=$tUSER_id;
  	 						$GLOBALS{tUSER_TYPE_value}=$tUSER_TYPE_value;
  							$GLOBALS{tAGENCY_value}=$tAGENCY_value;
  							$GLOBALS{tAGENCY_id}=$tAGENCY_id;
 							
	              if($XMLaction eq "user_profile_functions_user_profile_list"){$gResponseXml = $Functions->user_profile_functions_user_profile_list($receivedHash);}
	              elsif($XMLaction eq "user_profile_functions_user_profile_edit"){$gResponseXml = $Functions->user_profile_functions_user_profile_edit($receivedHash);}
	              elsif($XMLaction eq "user_profile_functions_user_profile_add"){$gResponseXml = $Functions->user_profile_functions_user_profile_add($receivedHash);}

	              elsif($XMLaction eq "user_profile_functions_user_profile_picture_list"){$gResponseXml = $Functions->user_profile_functions_user_profile_picture_list($receivedHash);}
	              elsif($XMLaction eq "user_profile_functions_user_profile_picture_add"){$gResponseXml = $Functions->user_profile_functions_user_profile_picture_add($receivedHash);}
	              elsif($XMLaction eq "user_profile_functions_user_profile_picture_delete"){$gResponseXml = $Functions->user_profile_functions_user_profile_picture_delete($receivedHash);}
	            
	            
	              else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}	            
	            }
	          }
          }
          elsif(substr($XMLaction,0,24) eq "user_category_functions_")
          {
            my $Functions = new My_UserCategoryFunctions ($gdbhMain,\%GLOBALS);
                        
            if($XMLaction eq "user_category_functions_user_category_types_list"){$gResponseXml = $Functions->user_category_functions_user_category_types_list($receivedHash);}
            else
            {
  						my $User_Functions = new My_UserFunctions($gdbhMain,\%GLOBALS);
						  my ($tUSER_id,$tUSER_TYPE_value,$tAGENCY_value,$tAGENCY_id,$active) = $User_Functions->internal_validate_session($receivedHash);
						  if($tUSER_id==-1)
						  {
						    $gResponseXml = (My_GenericFunctions->return_error("Invalid Session_id.","warn"));
						  }
						  else
						  {	
  							$GLOBALS{tUSER_id}=$tUSER_id;
  							$GLOBALS{tUSER_TYPE_value}=$tUSER_TYPE_value;
  							$GLOBALS{tAGENCY_value}=$tAGENCY_value;
  							$GLOBALS{tAGENCY_id}=$tAGENCY_id;
 							
	              if($XMLaction eq "user_category_functions_user_category_list"){$gResponseXml = $Functions->user_category_functions_user_category_list($receivedHash);}
	              elsif($XMLaction eq "user_category_functions_user_category_add"){$gResponseXml = $Functions->user_category_functions_user_category_add($receivedHash);}
	              elsif($XMLaction eq "user_category_functions_user_category_delete"){$gResponseXml = $Functions->user_category_functions_user_category_delete($receivedHash);}
	              elsif($XMLaction eq "user_category_functions_user_category_edit"){$gResponseXml = $Functions->user_category_functions_user_category_edit($receivedHash);}
	            
  	            else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
  	          }
            }                      
          }
          elsif(substr($XMLaction,0,28) eq "user_notification_functions_")
          {
            my $Functions = new My_UserNotificationsFunctions ($gdbhMain,\%GLOBALS);
                        
  						my $User_Functions = new My_UserFunctions($gdbhMain,\%GLOBALS);
						  my ($tUSER_id,$tUSER_TYPE_value,$tAGENCY_value,$tAGENCY_id,$active) = $User_Functions->internal_validate_session($receivedHash);
						  if($tUSER_id==-1)
						  {
						    $gResponseXml = (My_GenericFunctions->return_error("Invalid Session_id.","warn"));
						  }
						  else
						  {
	
  							$GLOBALS{tUSER_id}=$tUSER_id;
  							$GLOBALS{tUSER_TYPE_value}=$tUSER_TYPE_value;
  							$GLOBALS{tAGENCY_value}=$tAGENCY_value;
  							$GLOBALS{tAGENCY_id}=$tAGENCY_id;
							
  	            if($XMLaction eq "user_notification_functions_user_notification_list"){$gResponseXml = $Functions->user_notification_functions_user_notification_list($receivedHash);}
  	            elsif($XMLaction eq "user_notification_functions_user_notification_edit"){$gResponseXml = $Functions->user_notification_functions_user_notification_edit($receivedHash);}
  	            elsif($XMLaction eq "user_notification_functions_user_notification_delete"){$gResponseXml = $Functions->user_notification_functions_user_notification_delete($receivedHash);}
   	            
	              else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
	            }
          }
          elsif(substr($XMLaction,0,21) eq "user_event_functions_")
          {
            my $Functions = new My_UserEventFunctions ($gdbhMain,\%GLOBALS);
                        
  						my $User_Functions = new My_UserFunctions($gdbhMain,\%GLOBALS);
						  my ($tUSER_id,$tUSER_TYPE_value,$tAGENCY_value,$tAGENCY_id,$active) = $User_Functions->internal_validate_session($receivedHash);
						  if($tUSER_id==-1)
						  {
						    $gResponseXml = (My_GenericFunctions->return_error("Invalid Session_id.","warn"));
						  }
						  else
						  {
	
  							$GLOBALS{tUSER_id}=$tUSER_id;
  							$GLOBALS{tUSER_TYPE_value}=$tUSER_TYPE_value;
  							$GLOBALS{tAGENCY_value}=$tAGENCY_value;
  							$GLOBALS{tAGENCY_id}=$tAGENCY_id;
							
  	            if($XMLaction eq "user_event_functions_event_list"){$gResponseXml = $Functions->user_event_functions_event_list($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_add"){$gResponseXml = $Functions->user_event_functions_event_add($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_view"){$gResponseXml = $Functions->user_event_functions_event_view($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_delete"){$gResponseXml = $Functions->user_event_functions_event_delete($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_edit"){$gResponseXml = $Functions->user_event_functions_event_edit($receivedHash);}

  	            elsif($XMLaction eq "user_event_functions_event_check_in"){$gResponseXml = $Functions->user_event_functions_event_check_in($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_check_out"){$gResponseXml = $Functions->user_event_functions_event_check_out($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_user_review"){$gResponseXml = $Functions->user_event_functions_event_user_review($receivedHash);}

  	            elsif($XMLaction eq "user_event_functions_event_status_list"){$gResponseXml = $Functions->user_event_functions_event_status_list($receivedHash);}
  	            
  	            elsif($XMLaction eq "user_event_functions_user_status_list"){$gResponseXml = $Functions->user_event_functions_user_status_list($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_user_status_edit"){$gResponseXml = $Functions->user_event_functions_user_status_edit($receivedHash);}

  	            elsif($XMLaction eq "user_event_functions_event_user_add"){$gResponseXml = $Functions->user_event_functions_event_user_add($receivedHash);}
  	            elsif($XMLaction eq "user_event_functions_event_user_delete"){$gResponseXml = $Functions->user_event_functions_event_user_delete($receivedHash);}

  	            elsif($XMLaction eq "user_event_functions_agency_accept_booking"){$gResponseXml = $Functions->user_event_functions_agency_accept_booking($receivedHash);}

  	            elsif($XMLaction eq "user_event_functions_event_make_payment"){$gResponseXml = $Functions->user_event_functions_event_make_payment($receivedHash);}

  	            elsif($XMLaction eq "user_event_functions_category_edit"){$gResponseXml = $Functions->user_event_functions_category_edit($receivedHash);}

   	            
	              else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
	            }
          }
          elsif(substr($XMLaction,0,5) eq "cron_")
          {
            my $Functions = new My_CronFunctions($gdbhMain,\%GLOBALS);
            
            if($XMLaction eq "cron_expire_user_sessions"){$gResponseXml = $Functions->cron_expire_user_sessions($receivedHash);}
            elsif($XMLaction eq "cron_expire_user_event_request"){$gResponseXml = $Functions->cron_expire_user_event_request($receivedHash);}
            elsif($XMLaction eq "cron_notification_reminders"){$gResponseXml = $Functions->cron_notification_reminders($receivedHash);}
            elsif($XMLaction eq "cron_event_reminders"){$gResponseXml = $Functions->cron_event_reminders($receivedHash);}
            elsif($XMLaction eq "cron_new_staff"){$gResponseXml = $Functions->cron_new_staff($receivedHash);}
            
            else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
          }  

          elsif($XMLaction eq "retrieve_api_descriptor"){$gResponseXml = retrieve_api_descriptor($receivedHash);}

          else{$gResponseXml = My_GenericFunctions->return_error("No Such Action Defined.","");}
          #-------------------------------------------------------------------------------------------------------
          # End Function If Check
          #-------------------------------------------------------------------------------------------------------
        }
        $gdbhMain->disconnect;        
      }
    }
  }    
#     my $sth = $gdbhMain->prepare("COMMIT");
#     $GLOBALLOGGERHANDLE->info("COMMIT");
#     $sth->execute;
#     

  my $EnGNime=Time::HiRes::time();

  if($call_type ne "MEMCACHE")
  {
    My_GenericFunctions->SaveMemCacheResponse($receivedXML,$gResponseXml,$GLOBALS{"CACHE_response_$XMLaction"});   
  }
  
  if($gRequestType eq "XML" || $gRequestType eq "")
  {
    print $gResponseXml;
    $gResponseXml =~ s/\n//ig;
    $GLOBALLOGGERHANDLE->info("".$gResponseXml."");
  }
  elsif($gRequestType eq "JSON")
  {
    my $responseHash = XMLin($gResponseXml,SuppressEmpty => undef);
    my $json_text = encode_json($responseHash);
    print $json_text;
    $json_text =~ s/\n//ig;
    $GLOBALLOGGERHANDLE->info("".$json_text."");   
  }
  $GLOBALLOGGERHANDLE->info("");
  $GLOBALLOGGERHANDLE->info("EventStaffSystem Function($XMLaction"."$call_type) StartTime($StartTime) EndTime($EnGNime) (".($EnGNime-$StartTime).")");
  $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");
  $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");
  $GLOBALLOGGERHANDLE->info("----------------------------------------------------------------------------------------");
  $GLOBALLOGGERHANDLE->info("");
  $GLOBALLOGGERHANDLE->info("");


}

#--------------------------------------------------------------------------------------------------
sub read_request()
{
  my $tmpXml="";
  my $line="";
  
  $GLOBALLOGGERHANDLE = Log::Log4perl->get_logger();
  
  if($query->param("POSTDATA") ne "")
  {
    $tmpXml= $query->param("POSTDATA");
  }
  else
  {
    undef $/;

    $tmpXml = <STDIN>;
#     while (defined($line = <STDIN>))
#     {
# #$GLOBALLOGGERHANDLE->info( "$line");  
#       $tmpXml .= $line;
#       if (index($tmpXml,"</api>") != -1)
#       {
#         return $tmpXml;
#       }
#     }
    
    $/ = "\n";    
  }

  return $tmpXml;
}

#--------------------------------------------------------------------------------------------------
sub LoadGlobals
{
  my $line;

  #print "CONF FILE $CONFIGPATH\n";
  open(INFILE, "<".$CONFIGPATH);
  while($line = <INFILE>)
  {
    chomp($line);

    if(substr($line,0,1) ne "#")
    {
      my @arr = split(/~~/,$line);

      #warn "$arr[0] || $arr[1]\n";
      #$GLOBALLOGGERHANDLE->info("$arr[0] || $arr[1]");
      $arr[1]=~s/\r//g;
      $GLOBALS{$arr[0]} = $arr[1];
    }
  }
  close(INFILE);
}

#--------------------------------------------------------------------------------------------------
sub xml_friendly($)
{
  my($msg) = @_;
  my $loop=0;
  my $rep;
  my $repchar;

  $msg =~ s/\&/\&amp;/ig;
  $msg =~ s/\"/\\\'/ig;
  $msg =~ s/\</\&lt;/ig; #break the xml
  $msg =~ s/\>/\&gt;/ig; #break the xml

  for($loop=1;$loop<32;$loop++)
  {
    if($loop==10 || $loop==13)
    {
    }
    else
    {
      $rep = "&#$loop;";
      $repchar = chr($loop);
      $msg =~ s/$repchar/$rep/ig;
    }
  }

  for($loop=128;$loop<256;$loop++)
  {
    if ($loop != 223)
    {
      $rep = "&#$loop;";
      $repchar = chr($loop);
      $msg =~ s/$repchar/$rep/ig;
    }
  }

  return($msg);
}

#--------------------------------------------------------------------------------------------------
sub make_param_xml($$$$)
{
  my($hash,$depth,$parent,$param_desc) = @_;
  my $cxml="";
  
  
  #$GLOBALLOGGERHANDLE->info("$depth,$parent");
  
  my $space = "";
  for(my $sx=0;$sx<$depth+1;$sx++)
  {
    $space .= " ";
  }
  
  my $tmp = $hash->{$depth};
  #if(!defined($tmp)) { return($cxml); }
  #if(ref($tmp) eq "HASH") {$cxml .= "\n";}
  foreach my $function (sort keys %$tmp)
  {
    my $add = 0;
    if($parent eq ""){$add=1;}
    elsif(index($function,"$parent>")>-1) {$function = substr($function,length($parent)+1); $add=1;}
    
    #warn "$depth|$add|$function\n";
    if($add==1)
    {
      if($function ne "")
      {
        $cxml .= "\n$space<$function>";
        
        if(index(lc($param_desc),lc($function))==-1 && $function ne "action_content" && $function ne "session_id")
        {
          $GLOBALLOGGERHANDLE->info("No Description for $function ($depth) in ".Dumper($hash));
          exit;
        }
        $cxml .= make_param_xml($hash,($depth+1),$function,$param_desc);
          
        $cxml .= "$space</$function>\n";
      }
    }
  }
  
  return ($cxml);
}

#--------------------------------------------------------------------------------------------------
sub retrieve_api_descriptor($)
{
  my ($xml) = @_;
  my $frxml="";
  my $rxml="";
  my $session_id;
  my $statement ="";
  my $sth;
  my @row;
  my $funChk=0;
  my $DESCRIPTOR;
  my $DESCRIPTOR_count=-1;
  
  my $FILE_DATA="";
  my $folder="/var/www/EventStaffAPI/* /var/www/EventStaffAPI/APILibs/*";
  my $api_file="/var/www/EventStaffAPI/API_DOC.html";
  my $api_file_int="/var/www/EventStaffAPI/API_DOC_Int.html";
  my $line;
  my $function_start=0;
  my $iHash;
  my $oHash;
  my $inputParams=0;
  my $outputParams=0;
  my $inputParamsDesc=0;
  my $outputParamsDesc=0;
  my $function_name;
  my $function_counter=0;
  
  my $temp_str;
  my @arr;
  my $x;
  my $key;

  my $change_date ="";
  my $change_desc ="";
  my $change_auth ="";
  my $change_type ="";
  my $revision_history="";
  my $revision_counter=1;
  my $module_name;
  
  open(INFOLDER,"/bin/ls -1 $folder |");
  $GLOBALLOGGERHANDLE->info("/bin/ls -1 $folder |");
  while(my $file = <INFOLDER>)
  {
    chomp($file);
    $function_start=0;    
    $inputParams=0;
    $inputParamsDesc=0;
    $outputParams=0;
    $outputParamsDesc=0;
    
    $module_name = substr($file,rindex($file,"/")+1,-3);
      
    $GLOBALLOGGERHANDLE->info("$file");
    open(INFILE,"< $file");
    while($line = <INFILE>)
    {
      chomp($line);
      if($function_start==0 && index($line,"#\@function")>-1)  ##Look for Start
      {
        $function_start=1;    
        $inputParams=0;
        $inputParamsDesc=0;
        $outputParams=0;
        $outputParamsDesc=0;
        undef %{$iHash};
        undef %{$oHash};
        
        $function_name = substr($line,index($line,"\@function")+length("\@function")+1);
        $GLOBALLOGGERHANDLE->info("#--------------------------------------------------------------------------------------------------");
        $GLOBALLOGGERHANDLE->info("#$function_name");
        $DESCRIPTOR->{$function_counter}->{'function_name'}=$function_name;
        $function_name=$function_counter++;
      }
      if($function_start==0)  ##Look for Start
      {
        if(index($line,"#\@change_date")>-1)
        {
          $change_date = substr($line,index($line,"\@change_date")+length("\@change_date")+1);        
        }
        if(index($line,"#\@change_desc")>-1)
        {
          $change_desc = substr($line,index($line,"\@change_desc")+length("\@change_desc")+1);        
        }
        if(index($line,"#\@change_auth")>-1)
        {
          $change_auth = substr($line,index($line,"\@change_auth")+length("\@change_auth")+1);        
        }
        
        if($change_date ne "" && $change_desc ne "" && $change_auth ne "")
        {
          $revision_history .= "
            <tr>
              <td>$change_auth</td>
              <td>0.".$revision_counter++."</td>
              <td>$change_date</td>
              <td>$change_desc</td>
            </tr>
          ";

          $change_date ="";
          $change_desc ="";
          $change_auth ="";
        }
      }
      if($function_start==1)
      {
        if(index($line,"\@document_class")>-1)
        {
          $function_start=0;
          $DESCRIPTOR->{$function_name}->{'document_class'} = substr($line,index($line,"\@document_class")+length("\@document_class")+1);
          
          $DESCRIPTOR->{$function_name}->{'module_name'}= $module_name;
          
          $temp_str="<\?xml version=\"1.0\"\?>\n<api>\n";
          $temp_str.=make_param_xml($iHash,0,"",$DESCRIPTOR->{$function_name}->{'in_param'})."</api>";
          #warn "|$temp_str|\n";   
          #$temp_str =~ s/\ //ig;
          $DESCRIPTOR->{$function_name}->{'xml_in'}=$temp_str;          
            my $responseHash = XMLin($temp_str,SuppressEmpty => undef);
            my $json_text = encode_json($responseHash);
            $DESCRIPTOR->{$function_name}->{'json_in'}=$json_text;
            #warn "|$json_text|\n";   
          

          $temp_str="<\?xml version=\"1.0\"\?>\n<api>\n";
          $temp_str.=make_param_xml($oHash,0,"",$DESCRIPTOR->{$function_name}->{'out_param'})."</api>";
          #warn "|$temp_str|\n";   
          #$temp_str =~ s/\ //ig;
          $DESCRIPTOR->{$function_name}->{'xml_out'}=$temp_str;
            my $responseHash = XMLin($temp_str,SuppressEmpty => undef);
            my $json_text = encode_json($responseHash);
            $DESCRIPTOR->{$function_name}->{'json_out'}=$json_text;          
            #warn "|$json_text|\n";   
        }
        else
        {
          #@description Apply for access to a country service number
          if(index($line,"\@description")>-1 && $DESCRIPTOR->{$function_name}->{'function_desc'} eq "")
          {
            $DESCRIPTOR->{$function_name}->{'function_desc'}=substr($line,index($line,"\@description")+length("\@description")+1);
          }
          
          if((index($line,"\@params")>-1 || $inputParams==1)  && index($line,"\@params_description")==-1)
          {
            $inputParams=1;
            $inputParamsDesc=0;
            $outputParams=0;
            $outputParamsDesc=0;
            if(index($line,"\@params")>-1)
            {
              $line = "#".substr($line,index($line,"\@params")+length("\@params")+1);
              #$GLOBALLOGGERHANDLE->info("Start (\@params) $line");
            }
          }
            if(index($line,"\@params_description")>-1 || $inputParamsDesc==1)
            {
              $inputParams=0;
              $inputParamsDesc=1;
              $outputParams=0;
              $outputParamsDesc=0;
              if(index($line,"\@params_description")>-1)
              {
                $line = "#".substr($line,index($line,"\@params_description")+length("\@params_description")+1);     
                #$GLOBALLOGGERHANDLE->info("Start (\@params_description) $line");
              }
            }
                    
          if((index($line,"\@return")>-1 || $outputParams==1)  && index($line,"\@return_description")==-1)
          {
            $inputParams=0;
            $inputParamsDesc=0;
            $outputParams=1;
            $outputParamsDesc=0;
            if(index($line,"\@return")>-1)
            {
              $line = "#".substr($line,index($line,"\@return")+length("\@return")+1);        
              #$GLOBALLOGGERHANDLE->info("Start (\@return) $line");
            }
          }
            if(index($line,"\@return_description")>-1 || $outputParamsDesc==1)
            {
              $inputParams=0;
              $inputParamsDesc=0;
              $outputParams=0;
              $outputParamsDesc=1;
              if(index($line,"\@return_description")>-1)
              {
                $line = "#".substr($line,index($line,"\@return_description")+length("\@return_description")+1);
                #$GLOBALLOGGERHANDLE->info("Start (\@return_description) $line");
              }
            }
          
          #$GLOBALLOGGERHANDLE->info("$function_name : inputParams:$inputParams inputParamsDesc:$inputParamsDesc outputParams:$outputParams outputParamsDesc:$outputParamsDesc");
          
          if($inputParams==1)
          {
            $line =~ s/-\>/\>/ig;
            #$GLOBALLOGGERHANDLE->info("InputPArams $line\n");
            @arr = split(/\>/,substr($line,1));
            for($x=0;$x<@arr;$x++)
            {
              $key = $arr[$x];
              if($x>0) { $key = $arr[$x-1].">".$key; }
              $iHash->{$x}->{$key}="1";
            }
          }
            if($inputParamsDesc==1)
            {
              if($line ne "#")
              {
                $DESCRIPTOR->{$function_name}->{'in_param'}.=substr($line,1)."<BR>\n";
              }
            }
          
          if($outputParams==1)
          {
            $line =~ s/-\>/\>/ig;
            @arr = split(/\>/,substr($line,1));
            for($x=0;$x<@arr;$x++)
            {
              $key = $arr[$x];
              if($x>0) { $key = $arr[$x-1].">".$key; }
              $oHash->{$x}->{$key}="1";
            }
          }
          
          if($outputParamsDesc==1)
          {
            if($line ne "#")
            {
              $DESCRIPTOR->{$function_name}->{'out_param'}.=substr($line,1)."<BR>\n";
            }
          }
        }
      }      
    }
    close(INFILE);
  }
  close(INFOLDER);
  
  my $key;
  my $paramkey;
  my $paramHash;
  my $index_data ;
  my $api_call_data = "";
  my $index_data_int ;
  my $api_call_data_int = "";  
  my $API_DOC;
  my $this_section;
  my $old_section;

  foreach $key (sort {$a <=> $b} keys %$DESCRIPTOR)
  {
    if($key ne "" && $DESCRIPTOR->{$key}->{'module_name'} ne "")
    {
      #my $statement = "insert ignore into dbVODDBControl.tUNIT_TEST_DETAILS (api_call) values (\"".$DESCRIPTOR->{$key}->{'function_name'}."\") ";
      ##$GLOBALLOGGERHANDLE->info("$statement");
      #my $sth = $gdbhMain->prepare($statement);
      #$sth->execute; 
      
      $module_name = $DESCRIPTOR->{$key}->{'module_name'};
      $rxml.="<descriptor_item>";
      #$rxml.="    <module_name>".xml_friendly($DESCRIPTOR->{$key}->{'FUNCTION_DETAILS'}->{'module_name'})."</module_name>";
      $rxml.="    <function_name>".xml_friendly($DESCRIPTOR->{$key}->{'function_name'})."</function_name>";
      $rxml.="    <function_description>".xml_friendly($DESCRIPTOR->{$key}->{'function_desc'})."</function_description>";
      $rxml.="    <incoming_xml>";
      $rxml.= xml_friendly($DESCRIPTOR->{$key}->{'xml_in'});
      $rxml.="    </incoming_xml>";
      $rxml.="    <incoming_json>";
      $rxml.= xml_friendly($DESCRIPTOR->{$key}->{'json_in'});
      $rxml.="    </incoming_json>";
      $rxml.="    <incoming_param_desc>";
      $rxml.= xml_friendly($DESCRIPTOR->{$key}->{'in_param'});
      $rxml.="    </incoming_param_desc>";
      
      $rxml.="    <return_xml>";
      $rxml.= xml_friendly($DESCRIPTOR->{$key}->{'xml_out'});
      $rxml.="    </return_xml>";
      $rxml.="    <return_json>";
      $rxml.= xml_friendly($DESCRIPTOR->{$key}->{'json_out'});
      $rxml.="    </return_json>";
      $rxml.="    <return_param_desc>";
      $rxml.= xml_friendly($DESCRIPTOR->{$key}->{'out_param'});
      $rxml.="    </return_param_desc>";
            
      $rxml.="</descriptor_item>";
      
      $this_section = substr($DESCRIPTOR->{$key}->{'function_name'},0,rindex($DESCRIPTOR->{$key}->{'function_name'},"_"));
      if($old_section ne $this_section)
      {
        $index_data->{$module_name} .= "<BR>\n";
        $index_data_int->{$module_name} .= "<BR>\n";
        $old_section = $this_section;        
      }
      
      if(lc($DESCRIPTOR->{$key}->{'document_class'}) eq "both" || lc($DESCRIPTOR->{$key}->{'document_class'}) eq "external")
      {
        $index_data->{$module_name} .= "   <a href=\"#".$DESCRIPTOR->{$key}->{'function_name'}."\">".$DESCRIPTOR->{$key}->{'function_desc'}."</a><br>\n";
        $api_call_data .= "<!-- ####################################################################################################################### -->
  <!-- ####################################################################################################################### -->
  <!-- ####################################################################################################################### -->
  <div class='break'></div>
  <h3><a name='".$DESCRIPTOR->{$key}->{'function_name'}."'>".$DESCRIPTOR->{$key}->{'function_name'}."</a></h3>
  <h5>Description:</h5>
  ".$DESCRIPTOR->{$key}->{'function_desc'}."<br>
  <table>
  <tr>
  <td>
  <h5>Sent Xml:</h5>
  <textarea cols='80' rows='10' readOnly='true' id='xml_in_doUserLogin' name='xml_in_doUserLogin'>".$DESCRIPTOR->{$key}->{'xml_in'}."
  </textarea>
  <h5>Sent Json:</h5>
  <textarea cols='80' rows='5' readOnly='true' id='xml_in_doUserLogin' name='xml_in_doUserLogin'>".$DESCRIPTOR->{$key}->{'json_in'}."
  </textarea>
  </td>
  </tr>
  </table>
  <br>
  <h5>Info:</h5><blockquote>
  ".$DESCRIPTOR->{$key}->{'in_param'}."<br>
  </blockquote>
  <table>
  <tr>
  <td>
  <h5>Reply Xml:</h5>	
  <textarea cols='80' rows='10' readOnly='true' id='xml_out_doUserLogin' name='xml_out_doUserLogin'>".$DESCRIPTOR->{$key}->{'xml_out'}."
  </textarea>
  <h5>Reply Json:</h5>
  <textarea cols='80' rows='5' readOnly='true' id='xml_out_doUserLogin' name='xml_out_doUserLogin'>".$DESCRIPTOR->{$key}->{'json_out'}."
  </textarea>
  </td>
  </tr>
  </table>
  <br>
  <h5>Info:</h5><blockquote>
  ".$DESCRIPTOR->{$key}->{'out_param'}."<br>
  </blockquote>
  <a title='Back to Index' href='#Index'>Back to Index</a>
      <div class='bottom_box'>Copyright &copy; 2015 Smartcall</div>
      


  ";
      }
      if(lc($DESCRIPTOR->{$key}->{'document_class'}) eq "both" || lc($DESCRIPTOR->{$key}->{'document_class'}) eq "internal")
      {
        $index_data_int->{$module_name} .= "   <a href=\"#".$DESCRIPTOR->{$key}->{'function_name'}."\">".$DESCRIPTOR->{$key}->{'function_desc'}."</a><br>\n";
        $api_call_data_int .= "<!-- ####################################################################################################################### -->
  <!-- ####################################################################################################################### -->
  <!-- ####################################################################################################################### -->
  <div class='break'></div>
  <h3><a name='".$DESCRIPTOR->{$key}->{'function_name'}."'>".$DESCRIPTOR->{$key}->{'function_name'}."</a></h3>
  <h5>Description:</h5>
  ".$DESCRIPTOR->{$key}->{'function_desc'}."<br>
  <table>
  <tr>
  <td>
  <h5>Sent Xml:</h5>
  <textarea cols='80' rows='10' readOnly='true' id='xml_in_doUserLogin' name='xml_in_doUserLogin'>
  ".$DESCRIPTOR->{$key}->{'xml_in'}."
  </textarea>
  <h5>Sent Json:</h5>
  <textarea cols='80' rows='5' readOnly='true' id='xml_in_doUserLogin' name='xml_in_doUserLogin'>
  ".$DESCRIPTOR->{$key}->{'json_in'}."
  </textarea>
  </td>
  </tr>
  </table>
  <br>
  <h5>Info:</h5><blockquote>
  ".$DESCRIPTOR->{$key}->{'in_param'}."<br>
  </blockquote>
  <table>
  <tr>
  <td>
  <h5>Reply Xml:</h5>	
  <textarea cols='80' rows='10' readOnly='true' id='xml_out_doUserLogin' name='xml_out_doUserLogin'>
  ".$DESCRIPTOR->{$key}->{'xml_out'}."
  </textarea>
  <h5>Reply Json:</h5>
  <textarea cols='80' rows='5' readOnly='true' id='xml_out_doUserLogin' name='xml_out_doUserLogin'>
  ".$DESCRIPTOR->{$key}->{'json_out'}."
  </textarea>
  </td>
  </tr>
  </table>
  <br>
  <h5>Info:</h5><blockquote>
  ".$DESCRIPTOR->{$key}->{'out_param'}."<br>
  </blockquote>
  <a title='Back to Index' href='#Index'>Back to Index</a>
      <div class='bottom_box'>Copyright &copy; 2015 Smartcall</div>
      


  ";
      }
    }
  }
  
  
  $API_DOC = "<html>
  <head>
    <title>API Documentation</title>

    <style  type=\"text/css\">
      .break 
      { 
        page-break-before: always; 
      }

      .cover_sheet 
      {
        background-position: 0% 0%;
        background-repeat: no-repeat;
      }

      .history 
      {
      }

      .index 
      {
      }

      .data 
      {
      }

      .bottom_box
      {
        background-color: grey;
        background-position: 98% 100%;
        background-repeat: no-repeat;
        width: 100%;
        float:left;
      }

      h5
      {
        margin:5px 0px 0px 0px;
        text-decoration:underline;
      }

      h3
      {
        margin:25px 0px 0px 0px;
        text-decoration:underline;
      }

      body
      {
        font-size:10pt;
      }


    </style>    
  </head>

  <body>
   <div id='cover_sheet' class='cover_sheet'> <img src='FrontCover.png'> 
    <div class='bottom_box'>Copyright &copy; 2015 Smartcall</div>
   </div>

   <div id='history' class='history'>
    <h2><b><u>Revision History:</u></b></h2>
    <table border=1>
      <tr>
        <td width='200px'><b>Author</b></td>
        <td width='100px'><b>Version</b></td>
        <td width='100px'><b>Date</b></td>
        <td width='400px'><b>Description</b></td>
      </tr>
      $revision_history
    </table>
    <div class='bottom_box'>Copyright &copy; 2015 Smartcall</div>
   </div>

   <div id='index' class='index'>
    <div class='break'></div>
    <h2><a name='Index'>Index:</a></h2><br>
    <a href='#Notes'>Notes</a><br><br>
    ";    
    
  open(OUTFILE,"> $api_file");
  print OUTFILE "$API_DOC";
  foreach $module_name (sort keys $index_data)
  {
    if(index($index_data->{$module_name},"href")>-1)
    {
      print OUTFILE "<BR><BR><b>$module_name</b>".$index_data->{$module_name}."";
    }
  }
  print OUTFILE "$api_call_data";
  close(OUTFILE);    

  open(OUTFILE,"> $api_file_int");
  print OUTFILE "$API_DOC";
  foreach $module_name (sort keys $index_data_int)
  {
    if(index($index_data_int->{$module_name},"href")>-1)
    {
      print OUTFILE "<BR><BR><b>$module_name</b>".$index_data_int->{$module_name}."";
    }
  }
  print OUTFILE "$api_call_data_int";
  close(OUTFILE);    
  
  $frxml .= "<\?xml version=\"1.0\"\?>";
  $frxml .= "\n<api>";
  $frxml .= "\n<status>true</status>";
  $frxml .= "$rxml\n";
  $frxml .= "\n</api>";
  return($frxml);  
}

1;

