#!/geneva/geneva/dev1/perl5/bin/perl
#################################
#			       				#
# Program name: UDC.pl         	#
#			       				#
# Scope: Open file	       		#
#   	 Parse line by line 	#
#			       				#
#################################

#Declare used modules
use FileHandle;
use DBI;
use Time::Piece;
use Time::Seconds;


#Declare some constant
use constant NEWLINE                => "\n";

#Define database connection parameters
#my $instance = $ENV{"ORACLE_SID"} or die "Missing oracle instance!";
#my ($username, $password) = split(/\//,$ENV{"INTERFACE_DB"},2) or die "Missing connection credentials!";

#Define line variables
my $cdrsline;
my @cdr;

#Define length of each field
my @arrayLength = (1,4,2,3,14,2,8,4,6,16,1,5,14,14,2,10,14,8,4,2,14);

#Validation Variable
my $InvalidReason = undef;

#Fixed Call type
my $defCallType = 9;

#Define module initialization variables
my (%globalParameters);
my (@global_System_ID_List);
my (%eventTypes, %C, %callTypes, %propagatedCallTypes, %fieldsMapping, %systemInputFieldsCount);
my ($outputCDRFieldsCount);
my (%entities, %entitiesTrunkGroups, %entitiesIPAddresses, %trunkGroupTranslations);


# _________________________________________________________________________________________________
#
# Main
# _________________________________________________________________________________________________

#Open input file
sysopen(CDRSINPUTFILE, "in.dat",  O_RDONLY)
        or die "Cannot open log file for writing: $!";

#Open CDRs output file for writing
sysopen(CDRSOUTPUTFILE, "out.dat", O_WRONLY|O_TRUNC|O_CREAT)
		or die "Cannot open output file for writing: $!";

#Open CDRs discarded file for writing
sysopen(CDRSDISCARDEDFILE, "disc.dat", O_WRONLY|O_TRUNC|O_CREAT)
		or die "Cannot open output file for writing: $!";

#Initialize Parameters
initializeParameters() or die "Cannot initialize parameters: $!";

#Print header
printOutputFileHeader("event_file","EventRatingData","-v8");
$globalParameters{"GNV_NUMBER_PORTBILITY"}{"00302231200"}="TELLEPASSPORT";

my $i = 0;

#Read line by line
while (defined($cdrsline = <CDRSINPUTFILE>))
{
	#Chomp line
	chomp ($cdrsline);

	#Reset variables
	$InvalidReason = undef;
	$EventOUT = undef;
	
	#Split RAW into array
	@cdr = SplitRowByLength($cdrsline,@arrayLength);
	
	#Validate CDR
	$InvalidReason = vldUDC(\@cdr,$InvalidReason,$cdrsline);

	#If the CDRS is valide then whe can remap
	if ($InvalidReason eq undef)
	{
 	        #Create base output CDR
        	$outputCDR = setOutputCDRHeader();

			$xFieldValue  = '($cdr[0]';
			$xFieldValue .= ',\@cdr,\$cdrsline,\$dbh)';

			$outputCDR .= 	
				#Field 0
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLGInternationalFormatTelegramTEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 1
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLGEventTypeFIXTEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 2
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLGConvertDateTEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 3
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 4
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtCurrencyCode".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 5
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 6
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 7
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 8
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 9
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 10
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 11
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLGInternationalFormatTelegramTEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 12
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLGATTR2_int_natTEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 13
				$globalParameters{"OutputFileFieldSeparator"}.
				#Field 14
				$globalParameters{"OutputFileFieldSeparator"}.
				#Field 15
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLGATTR5_int_natTEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 16
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLG_PILOGES_TEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.
				#Field 17
				$globalParameters{"OutputFileFieldSeparator"}.
			 	eval ("fmtTLG_NUMBER_PORTABILITY_TEST".$xFieldValue).
				$globalParameters{"OutputFileFieldSeparator"}.
				$globalParameters{"OutputFileFieldDelimiter"}.NEWLINE;

           	print CDRSOUTPUTFILE $outputCDR;
	}
	else 
	{
		print CDRSDISCARDEDFILE $InvalidReason."\n";
	}
	
}

# _________________________________________________________________________________________________
#
# Subroutine:   initializeParameters
# Input:        Nothing
# Output:       Nothing
# Description:  Purpose of this subroutine is to initialize global and configuration paramters for
#               the MPP. In order to retrieve this information it connects to the Mediation DB and
#               loads the required data in memory.
# _________________________________________________________________________________________________
sub initializeParameters
{

	#In the real Program this variables ere retrived from a database

	$globalParameters{"OutputFileFieldSeparator"}="\"";
	$globalParameters{"OutputFileFieldDelimiter"}=';';	

	$globalParameters{"GNV_INTERF_MODIFIER"}{"11"}{"NATTLG"} = "NATIONAL";
	$globalParameters{"GNV_INTERF_MODIFIER"}{"10"}{"INTTLG"} = "INTERNATIONAL";

}


# _________________________________________________________________________________________________
#
# Subroutine:   SplitRowByLength
# Input:        Row, Array pattern
# Output:       Array with splitted field
# Description:  Purpose of this subroutine is to split an input row into separated variable. The 
#				Length of each fild is written in the input array.
# _________________________________________________________________________________________________
sub SplitRowByLength
{
    my ($xRow, @xArrayLength) = @_;
	my ($start, $i, $field_length) = (0,0,0);
	my (@field_array);

	$i=0;
	for $field_length (@xArrayLength)
 	{
		$field_array[$i] = substr ($xRow, $start, $field_length);
		#$field_array[$i]=$($xRow:start:field_length);
		$i++;
		$start+=$field_length;
	}

	return @field_array;
}

# _________________________________________________________________________________________________
#
# Subroutine:   generateOutputCDR
# Input:        Call type and Input Call Detail Record
# Output:       Formatted Output Call Detail Record
# Description:  Purpose of this subroutine is to transform the input CDR to the output CDR based on
#               the configured translation rules.
# _________________________________________________________________________________________________
sub generateOutputCDR
{
        my ($xDefCallType, $xInputCDR,$xeventDetailRecord,$xdbh) = @_;
        my ($xOutputCDR, $xOutputFormat, $xFieldValue, $xFormattedValue);

        #Assign CDR input fields to output fields
        OUTPUTFIELD: for my $i (0..$outputCDRFieldsCount)
        {
        #Only put field delimiter and process next output field if empty
        $xOutputCDR .= $globalParameters{"OutputFileFieldDelimiter"}
        and next OUTPUTFIELD unless (exists($fieldsMapping{$xDefCallType}{$i}[0]));

            #Put field separator
            $xOutputCDR .= $globalParameters{"OutputFileFieldSeparator"};
			
            #Retrieve output format function for specific call type and field
            $xOutputFormat = $fieldsMapping{$xDefCallType}{$i}[1];

            $xFieldValue  = '(@$xInputCDR[$fieldsMapping{$xDefCallType}{$i}[0]]';
			$xFieldValue .= ',\@$xInputCDR,$eventDetailRecord,$xdbh)';
			
             #Format output field based on required information and called formating function
            $xFormattedValue = $xOutputFormat.$xFieldValue;
            $xOutputCDR .= (eval $xFormattedValue);

            #Put field separator and delimiter
            $xOutputCDR .= $globalParameters{"OutputFileFieldSeparator"};
            $xOutputCDR .= $globalParameters{"OutputFileFieldDelimiter"};
		}

        chop($xOutputCDR);
        return $xOutputCDR.NEWLINE;
}




##################################################################
#
# Validate TLG TEST
#
#################################################################

# _________________________________________________________________________________________________
# Telegrams SERVICES VALIDATE
# Returns boolean to Validate CDRs
# _________________________________________________________________________________________________
sub vldUDC
{
   	my ($xInputCDR, $xInvalidReason, $xEventDetailRecord) = @_;
	my ($lengthCDR) = length $xEventDetailRecord;

	#Record Length must be 128   
	if ($lengthCDR != 149)
	{
        $xInvalidReason .= "[Invalid Row length (". $lengthCDR ." <> "."149 ".")] ";
	}

	#Expected Network Code value: 2
	elsif ($xInputCDR->[0] != 2)
	{
        $xInvalidReason .= "[Unexpected Network Code ( ".$xInputCDR->[0]." != 2 )] ";
	}

	#Expected Service Code value: 9510, 9520
	elsif ($xInputCDR->[1] != 9510 and $xInputCDR->[1] != 9520)
	{
        $xInvalidReason .= "[Unexpected Service Code ( ".$xInputCDR->[1]." != 9510 or 9520 )] ";
	}

	#Expected Transaction Code value: 60
	elsif ($xInputCDR->[2] != 60)
	{
        $xInvalidReason .= "[Unexpected Transaction Code ( ".$xInputCDR->[2]." != 60 )] ";
	}

	#Expected Rating Code value: 1, <space>
	elsif ($xInputCDR->[10] != 1 and $xInputCDR->[10] != ' ')
	{
        $xInvalidReason .= "[Unexpected Rating Code ( ".$xInputCDR->[10]." != 1, <space> )] ";
	}
 	
	#Copy the Input CDR into the HASH variable with all subCDR
	@{$inputCDR_HASH{"0"}} = @{$xInputCDR} if $xInputCDR != undef;

    return $xInvalidReason;
}


###################################################################################################
#
#	TELEGRAMS TEST !!!!! Sub
#
###################################################################################################

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED TELEPHON NUMBER IN INTERNATIONL FORMAT
# Returns the formatted Numer
# _________________________________________________________________________________________________
sub fmtTLGInternationalFormatTelegramTEST
{
	my ($xAnumber,$xInputCDR) = @_;
	$xAnumber = $xInputCDR->[4];
	$xAnumber =~ s/ //g;
	
	return $xAnumber if length $xAnumber !=0;
	return VOID;
}

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED EVENT TYPE
# Returns the formatted Event Type
# _________________________________________________________________________________________________
sub fmtTLGEventTypeFIXTEST
{

	return "1";
}

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED DATE
# Returns the formatted Numer
# _________________________________________________________________________________________________
sub fmtTLGConvertDateTEST
{
    my ($xInputField,$xInputCDR) = @_;
	my ($year,$mon,$mday,$hour,$min,$sec)= (substr($xInputCDR->[6],0,4),substr($xInputCDR->[6],4,2),
											substr($xInputCDR->[6],6,2),substr($xInputCDR->[7],0,2),
											substr($xInputCDR->[7],2,2),substr($xInputCDR->[7],4,2));
	return sprintf "%4d/%02d/%02d-%02d-%02d-%02d.00", $year,$mon,$mday,$hour,$min,$sec;
}

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED CURRENCY CODE
# Returns the formatted Numer
# _________________________________________________________________________________________________
sub fmtCurrencyCodeTEST
{

	my($xCurr) = "EUR";
	return $xCurr;
}

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED TELEPHON NUMBER IN INTERNATIONL FORMAT
# Returns the formatted Numer
# _________________________________________________________________________________________________
sub fmtTLGATTR2_int_natTEST
{
	my ($xServiceCode,$xInputCDR) = @_;

	return $xInputCDR->[20];
}

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED TELEPHON NUMBER IN INTERNATIONL FORMAT
# Returns the formatted Numer
# _________________________________________________________________________________________________
sub fmtTLGATTR5_int_natTEST
{
	my ($xServiceCode,$xInputCDR) = @_;

	$xServiceCode = $xInputCDR->[1];

	return $globalParameters{"GNV_INTERF_MODIFIER"}{"11"}{"NATTLG"} if $xServiceCode = 9510;
	return $globalParameters{"GNV_INTERF_MODIFIER"}{"10"}{"INTTLG"} if $xServiceCode = 9520;
}

# _________________________________________________________________________________________________
# TELEGRAMS: FORMATTED TELEPHON NUMBER IN INTERNATIONL FORMAT
# Returns the formatted Numer
# _________________________________________________________________________________________________
sub fmtTLG_PILOGES_TEST
{
	my ($xServiceCode,$xInputCDR,$xInputCDR_RAW,$xdbh) = @_;

	return "Test";
}


sub fmtTLG_NUMBER_PORTABILITY_TEST
{
	my ($A_Number) = @_;

	return "Test";
}

# _________________________________________________________________________________________________
#
# Subroutine:   setOutputCDRHeader
# Input:        Nothing
# Output:       Formatted header
# Description:  Purpose of this subroutine is to set the formatted header at the beginning of the
#               output CDR. (Geneva Billing System Format)
# _________________________________________________________________________________________________
sub setOutputCDRHeader
{
    return "Event: ";
}

# _________________________________________________________________________________________________
#
# Subroutine:   printOutputFileHeader
# Input:        Output file handle
# Output:       Nothing
# Description:  Purpose of this subroutine is to print the formatted header at the beginning of the
#               output file. (Geneva Billing System Format)
# _________________________________________________________________________________________________
sub printOutputFileHeader
{
    my($fileType, $fileSubType, $tag) = @_;

    print CDRSOUTPUTFILE
    (
        "Geneva: text_data_transfer_file\n"
        ."Format: 1\n"
        ."Character_set: ASCII8\n"
        ."File_type: $fileType\n"
        ."File_subtype: $fileSubType\n"
        ."File_group_number: 1\n"
        ."File_in_group_number: 0\n"
        ."Total_files_in_group: 1\n"
        ."Source_ID: source\n"
        ."Tag: $tag\n"
        ."# This file produced by MediationPostProcessor ".MLAVERSION."\n"
    );

    return 1;
}
