package Opals::SIF::SIF_MsgFactory;

# Version number
$VERSION   = 0.01;

use warnings;
use strict;
#################################################################
sub new {
    my ($class) = @_;
    my $self={};
    bless $self, $class;
    return $self;
}

#################################################################
sub createMessage{
    my ($self,$sifInfo,$msgType,$msgInfo)=@_;
    return Opals::SIF::SIFMessage->new($sifInfo,$msgType,$msgInfo);
}
#################################################################
#
# END package Opals::SIF::;SIF_MsgFactory
#
#################################################################


1;
#################################################################
package Opals::SIF::SIFMessage;
use strict;
#################################################################
#

my $msgFactoryFn={
    SIF_Register=>\&genRegisterMessage ,
    SIF_Unregister=>\&genUnregisterMessage ,
    SIF_Subscribe=>\&genSubscribeMessage ,
    SIF_Unsubscribe=>\&genUnsubscribeMessage ,
    SIF_Request=>\&genRequestMessage ,
    SIF_GetMessage=>\&genGetMessage ,
    SIF_Ack=>\&genACKMessage
};

#################################################################


sub new {
    my ($class,$sifInfo,$msgType,$msgInfo) = @_;
    my $self={};

    $self->{'sourceId'}     = $sifInfo->{'sourceId'}   || "";
    $self->{'sourceName'}   = $sifInfo->{'sourceName'} || "";
    $self->{'version'}      = $sifInfo->{'version'}    || "2.4";
    $self->{'authLevel'}    = $sifInfo->{'authLevel'}  || "0";
    $self->{'encryptLevel'} = $sifInfo->{'encryptLevel'}|| "0";
    $self->{'subscribes'}   = $sifInfo->{'subscribes'};
    $self->{'msgId'}         =_genGUID();
    $self->{'timestamp'}    =_getTimeStamp();
    $sifInfo->{'msgId'}=$self->{'msgId'};
    $sifInfo->{'timestamp'}=$self->{'timestamp'};

    $self->{'xml'}="";

    if(defined $msgFactoryFn->{$msgType}){
        $self->{'xml'}=$msgFactoryFn->{$msgType}($sifInfo,$msgInfo);
    }
   
    bless $self, $class;
    return $self;
}
#################################################################

sub getXml{
    my($self)=@_;
    return $self->{'xml'};
}
#################################################################

sub getMsgId{
    my($self)=@_;
    return $self->{'msgId'};

}
#################################################################

sub getSourcId{
    my($self)=@_;
    return $self->{'getSourcId'};

}
#################################################################

sub getSourceName{
    my($self)=@_;
    return $self->{'sourceName'};
}
#################################################################

sub getVersion{
    my($self)=@_;
    return $self->{'version'};
}
#################################################################


sub getMsgTimestamp{
    my($self)=@_;
    return $self->{'timestamp'};
}


#################################################################
1;

#################################################################
#
# END package Opals::SIF::SIFMessage;
#
#################################################################


#################################################################
sub genRegisterMessage{
    my ($sifInfo)=@_;
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  

    my $sourceName= $sifInfo->{'sourceName'};
    my $subscriberName= $sifInfo->{'subscriberName'};

    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x"  Version="$version">
  <SIF_Register>
$msgHeader
   <SIF_Name>$sourceName</SIF_Name>
   <SIF_Version>$version</SIF_Version>
  <SIF_Version>2.*</SIF_Version>
<SIF_MaxBufferSize>3072000</SIF_MaxBufferSize>
<SIF_Mode>Pull</SIF_Mode>
</SIF_Register>
</SIF_Message>
_STR_


    return $msg;
}
################################################################
sub genUnregisterMessage{
    my ($sifInfo)=@_;
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  

    my $sourceName= $sifInfo->{'sourceName'};
    my $subscriberName= $sifInfo->{'subscriberName'};

    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x"  Version="$version">
  <SIF_Unregister>
$msgHeader
</SIF_Unregister>
</SIF_Message>
_STR_


    return $msg;
}

#################################################################
sub genSubscribeMessage{
    my ($sifInfo)=@_;
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  
    my $subscribeXml=""; 
    foreach my $subObj (@{$sifInfo->{'subscribes'}}){
        $subscribeXml .=  "\n      <SIF_Object ObjectName=\"$subObj\" />";
    }

    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x" Version="$version">
  <SIF_Subscribe>
$msgHeader$subscribeXml        
  </SIF_Subscribe>
</SIF_Message>
_STR_


    return $msg;
}
#################################################################
sub genUnsubscribeMessage{
    my ($sifInfo)=@_;
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  
    my $subscribeXml=""; 
    foreach my $subObj (@{$sifInfo->{'subscribes'}}){
        $subscribeXml .=  "\n      <SIF_Object ObjectName=\"$subObj\" />";
    }

    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x"  Version="$version">
  <SIF_Unsubscribe>
$msgHeader$subscribeXml        
  </SIF_Unsubscribe>
</SIF_Message>
_STR_


    return $msg;
}

#################################################################
sub genRequestMessage{
    my ($sifInfo,$queryInfo)=@_;
    my $version= $sifInfo->{'version'};
    my $objName=$queryInfo->{'objectName'};

    my $msgHeader =getMsgHeader($sifInfo); 
    my $condXml=genQueryCond($queryInfo); 
    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  Version="$version">
  <SIF_Request>
$msgHeader
    <SIF_Version>$version</SIF_Version>
    <SIF_MaxBufferSize>3072000</SIF_MaxBufferSize>
    <SIF_Query>
      <SIF_QueryObject ObjectName="$objName" />
$condXml
    </SIF_Query>    
  </SIF_Request>
</SIF_Message>
_STR_
    return $msg;

}
#################################################################
sub genQueryCond{
    my($queryInfo)=@_;
    my $condXml="";
    if(defined $queryInfo->{'cond'}){
        my $xPath= $queryInfo->{'cond'}->{'xPath'};
        my $val= $queryInfo->{'cond'}->{'val'};
        my $op= $queryInfo->{'cond'}->{'operator'};
        $condXml=<<_TXT_;
      <SIF_ConditionGroup Type="None">
        <SIF_Conditions Type="None">
            <SIF_Condition>
                <SIF_Element>$xPath</SIF_Element>
                <SIF_Operator>$op</SIF_Operator>
                <SIF_Value>$val</SIF_Value>
          </SIF_Condition>
        </SIF_Conditions>
      </SIF_ConditionGroup>
_TXT_

    }
    return $condXml;

}
#################################################################
sub genGetMessage{
    my ($sifInfo)=@_;
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  

    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x" Version="$version">
  <SIF_SystemControl>
$msgHeader
  <SIF_SystemControlData>
      <SIF_GetMessage/>
    </SIF_SystemControlData>
  </SIF_SystemControl>
</SIF_Message>
_STR_


    return $msg;
}
#################################################################

sub genACKMessage{
    my ($sifInfo,$ackMsgInfo)=@_;
    my $ackMsg="";
    if(defined $ackMsgInfo->{'error'}){
       $ackMsg = genACKMessage_error($sifInfo,$ackMsgInfo);
    }
    else{
        $ackMsg = genACKMessage_ok($sifInfo,$ackMsgInfo);

    }
    return $ackMsg;

}
#################################################################

sub genACKMessage_ok{
    my ($sifInfo,$ackMsgInfo)=@_;
    my $originalSrcId =$ackMsgInfo->{"originalSourceId"} || "";
    my $originalMsgId =$ackMsgInfo->{"originalMsgId"} || "";
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  

    my $sifCode=$ackMsgInfo->{"SIF_Code"} || "1";
    my $sifData=$ackMsgInfo->{"SIF_Data"} || "";
 
    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x"  Version="$version">
  <SIF_Ack>
$msgHeader
    <SIF_OriginalSourceId>$originalSrcId</SIF_OriginalSourceId>
    <SIF_OriginalMsgId>$originalMsgId</SIF_OriginalMsgId>
    <SIF_Status>
      <SIF_Code>$sifCode</SIF_Code>
      <SIF_Data>$sifData</SIF_Data>
    </SIF_Status>   
    </SIF_Ack>
</SIF_Message>
_STR_

    $msg =~ s/ <SIF_Data><\/SIF_Data>//g;
    return $msg;
}

#################################################################

sub genACKMessage_error{
    my ($sifInfo,$ackErrorInfo)=@_;
    my $originalSrcId   =$ackErrorInfo->{"originalSourceId"} || "";
    my $originalMsgId   =$ackErrorInfo->{"originalMsgId"} || "";
    my $version= $sifInfo->{'version'};
    my $msgHeader =getMsgHeader($sifInfo);  

    my $category        =$ackErrorInfo->{"error"}->{"SIF_Cateogry"};  
    my $sifCode         =$ackErrorInfo->{"error"}->{"SIF_Code"};
    my $desc            =$ackErrorInfo->{"error"}->{"SIF_Desc"} || "";
    my $extDesc         =$ackErrorInfo->{"error"}->{"SIF_ExtendedDesc"} || "";

    my $msg=<<_STR_;
<SIF_Message  xmlns="http://www.sifinfo.org/infrastructure/2.x"  Version="$version">
  <SIF_Ack>
$msgHeader
    <SIF_OriginalSourceId>$originalSrcId</SIF_OriginalSourceId>
    <SIF_OriginalMsgId>$originalMsgId</SIF_OriginalMsgId>
    <SIF_Error>
      <SIF_Category>$category</SIF_Category>
      <SIF_Code>$sifCode</SIF_Code>
      <SIF_Desc>$desc</SIF_Desc>
      <SIF_ExtendedDesc>$extDesc</SIF_ExtendedDesc>
    </SIF_Error>
    </SIF_Ack>
</SIF_Message>
_STR_

    $msg =~ s/<SIF_OriginalSourceId><\/SIF_OriginalSourceId>/<SIF_OriginalSourceId  xsi:nil="true"><\/SIF_OriginalSourceId>/g;
    $msg =~ s/<SIF_OriginalMsgId><\/SIF_OriginalMsgId>/<SIF_OriginalMsgId  xsi:nil="true"><\/SIF_OriginalMsgId>/g;

    return $msg;

}

#################################################################


sub getMsgHeader{
    my ($sifInfo)=@_;
    my $authLevel    =$sifInfo->{'authLevel'}       || "0";
    my $encryptLevel = $sifInfo->{'encryptLevel'}   || "0";
    my $sourceId     =$sifInfo->{'sourceId'};
    my $version      = $sifInfo->{'version'};
    my $msgId         =$sifInfo->{'msgId'};
    my $timestamp    =$sifInfo->{'timestamp'} ;



    my $msgHeader= <<_STR_;
        <SIF_Header>
          <SIF_MsgId>$msgId</SIF_MsgId>
          <SIF_Timestamp>$timestamp</SIF_Timestamp>
          <SIF_Security>
            <SIF_SecureChannel>
              <SIF_AuthenticationLevel>$authLevel</SIF_AuthenticationLevel>
              <SIF_EncryptionLevel>$encryptLevel</SIF_EncryptionLevel>
            </SIF_SecureChannel>
          </SIF_Security>
          <SIF_SourceId>$sourceId</SIF_SourceId>
          <SIF_Contexts>
            <SIF_Context>SIF_Default</SIF_Context>
          </SIF_Contexts>
        </SIF_Header>
_STR_
    chomp $msgHeader;
    return $msgHeader;
}


#################################################################
#
sub _genGUID{
    my $guid=`uuidgen`;
    chomp $guid;

    $guid =~ s/-//g;
    $guid = uc($guid);
    return $guid;
}

#################################################################
sub _getTimeStamp{
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); 
    my $ts  =sprintf( "%04d-%02d-%02dT%02d:%02d:%02d", $year+1900,$mon,$mday,$hour,$min,$sec);
    return $ts;
}




#################################################################
