/** APPLICATION_PACKAGE.Z_REST_UTIL.Request.OnExecute **/
import EOEW_ETLAPI:COMMON:HashTable;

class Request
   method Request(&sURL As string);
   method get() Returns JsonObject;
   method post(&jsonRequest As JsonObject) Returns JsonObject;
   method generateRequest(&MethodName As string, &Request As string) Returns JsonObject;
   method buildGenericMessage(&MethodName As string, &Request As string) Returns Message;
   method base64ToString(&sBase64 As string) Returns string;
   method debugMessage(&sInMsg As string);
   
   property boolean Debug;
   property string Authorization;
   property string ContentType;
   property string Limit;
   property string RequestURL readonly;
   property EOEW_ETLAPI:COMMON:HashTable queryParams;
   
private
   method generateQueryString() Returns string;
   method isProd() Returns boolean;
   method isBase64Encoded(&inStr As string) Returns boolean;
end-class;

method Request
   /+ &sURL as String +/
   %This.queryParams = create EOEW_ETLAPI:COMMON:HashTable();
   %This.Debug = ( Not (%This.isProd()));
   %This.ContentType = "application/json; encoding=""UTF-8""";
   %This.Limit = "5";
   &RequestURL = &sURL;
   %This.queryParams.AddElement("onlyData", "True");
   %This.queryParams.AddElement("limit", %This.Limit);
end-method;

method get
   /+ Returns JsonObject +/
   Return %This.generateRequest("GET", "");
end-method;

method post
   /+ &jsonRequest as JsonObject +/
   /+ Returns JsonObject +/
   Return %This.generateRequest("POST", &jsonRequest.ToString());
end-method;

method generateRequest
   /+ &MethodName as String, +/
   /+ &Request as String +/
   /+ Returns JsonObject +/
   Local Message &msgResponse;
   Local string &sResponse;
   Local JsonObject &jsonResponse;
   
   &msgResponse = %IntBroker.ConnectorRequest(%This.buildGenericMessage(&MethodName, &Request), True);
   %This.debugMessage("STATUS " | &msgResponse.ResponseStatus);
   %This.debugMessage("HTTPResponseCode " | &msgResponse.HTTPResponseCode);
   
   If &msgResponse.ResponseStatus = %IB_Status_Success Then
      /** SUCCESS **/
      %This.debugMessage("SUCCESS");
   Else
      /** ERROR **/
      %This.debugMessage("ERROR");
      /** STOP  **/
      throw CreateException(0, 0, "Error Response. STATUS - " | &msgResponse.ResponseStatus | " , HTTPResponseCode - " | &msgResponse.HTTPResponseCode);
   End-If;
   
   &sResponse = %This.base64ToString(&msgResponse.GetContentString());
   
   try
      Local JsonParser &jsonParser = CreateJsonParser();
      If &jsonParser.Parse(&sResponse) Then
         &jsonResponse = &jsonParser.GetRootObject();
      End-If;
   catch Exception &exJsonParser
      %This.debugMessage(&exJsonParser.ToString());
      throw CreateException(0, 0, "Error : " | &sResponse);
   end-try;
   
   Return &jsonResponse;
   
end-method;

method buildGenericMessage
   /+ &MethodName as String, +/
   /+ &Request as String +/
   /+ Returns Message +/
   
   Local boolean &bRet;
   Local string &sURL;
   Local number &nCnt;
   Local array of string &arrQueryValue;
   Local Message &msgGeneric = CreateMessage(Message.IB_GENERIC);
   Local IBInfo &ibInfoGeneric = &msgGeneric.IBInfo;
   
   If &ibInfoGeneric.LoadConnectorProp("HTTPTARGET") Then
      
      %This.debugMessage("Content-Type " | %This.ContentType);
      
      &ibInfoGeneric.ConnectorOverride = True;
      &ibInfoGeneric.IBConnectorInfo.ConnectorClassName = "HttpTargetConnector";
      &ibInfoGeneric.IBConnectorInfo.ConnectorName = "HTTPTARGET";
      If Not (LTrim(%This.Authorization) = "") Then
         %This.debugMessage("Authorization" | " " | %This.Authorization);
         &bRet = &ibInfoGeneric.IBConnectorInfo.AddConnectorProperties("Authorization", %This.Authorization, %HttpHeader);
      End-If;
      &bRet = &ibInfoGeneric.IBConnectorInfo.AddConnectorProperties("Content-Type", %This.ContentType, %HttpHeader);
      &bRet = &ibInfoGeneric.IBConnectorInfo.DeleteConnectorProperties("URL");
      &bRet = &ibInfoGeneric.IBConnectorInfo.DeleteConnectorProperties("Method");
      
      &sURL = EncodeURL(&RequestURL);
      If Upper(&MethodName) = "GET" Then
         &sURL = &sURL | %This.generateQueryString();
      End-If;
      rem &sURL = EncodeURL(&sURL);
      %This.debugMessage(&MethodName | " " | &sURL);
      &bRet = &ibInfoGeneric.IBConnectorInfo.AddConnectorProperties("URL", &sURL, %HttpProperty);
      &bRet = &ibInfoGeneric.IBConnectorInfo.AddConnectorProperties("Method", Upper(&MethodName), %HttpProperty);
      
      
      If All(&Request) Then
         %This.debugMessage("Request " | &Request);
         &bRet = &msgGeneric.SetContentString(&Request);
      End-If;
      
   Else
      throw CreateException(0, 0, "Unable to Load Connector Property : HTTPTARGET");
   End-If;
   
   Return &msgGeneric;
end-method;

method base64ToString
   /+ &sBase64 as String +/
   /+ Returns String +/
   Local string &sResult;
   %This.debugMessage("Content " | &sBase64);
   /**
   -- If this method fails, probably the Encryption Algorithm Chain setup is missing
   -- Root >> PeopleTools >> Security >> Encryption >> Algorithm Chain
   -- Refer MOS Documents to setup or Execute below SQLs
   Insert into PSCRYPTCHNDEFN (CRYPT_CHAIN_ID,DESCR,DESCR254) values ('BASE64_DECRYPTED','Decrypt from Base64',' ');

   Insert into PSCRYPTALGCHAIN (CRYPT_CHAIN_ID,CRYPT_CHAIN_SEQ,CRYPT_ALG_ID) values ('BASE64_DECRYPTED',1,'PSUnicodeToAscii');
   Insert into PSCRYPTALGCHAIN (CRYPT_CHAIN_ID,CRYPT_CHAIN_SEQ,CRYPT_ALG_ID) values ('BASE64_DECRYPTED',2,'base64_decode');
   Insert into PSCRYPTALGCHAIN (CRYPT_CHAIN_ID,CRYPT_CHAIN_SEQ,CRYPT_ALG_ID) values ('BASE64_DECRYPTED',3,'PSAsciiToUnicode');

   Insert into PSCRYPTPRFL (CRYPT_PRFL_ID,CRYPT_CHAIN_ID,DESCR254,DESCR) values ('BASE64_DECRYPT','BASE64_DECRYPTED',' ','Decrypt from Base64');
   **/
   If %This.isBase64Encoded(&sBase64) Then
      
      try
         %This.debugMessage("Decoding Base64 Content . . .");
         Local object &cryDecode = CreateObject("Crypt");
         &cryDecode.Open("BASE64_DECRYPT");
         &cryDecode.UpdateData(&sBase64);
         &sResult = &cryDecode.Result;
         %This.debugMessage("Decoded Content " | &sResult);
         Return &sResult;
      catch Exception &exCrypt
         %This.debugMessage("Decoding Error : " | &exCrypt.ToString( False));
      end-try;
      
   End-If;
   
   Return &sBase64;
   
end-method;

method generateQueryString
   /+ Returns String +/
   Local array of string &arrQueryValue;
   Local string &sQuery;
   Local number &nCnt;
   
   &arrQueryValue = %This.queryParams.GetValues();
   
   For &nCnt = 1 To &arrQueryValue.Len
      If All(&arrQueryValue [&nCnt]) Then
         If &nCnt > 1 Then
            &sQuery = &sQuery | "&";
         End-If;
         &sQuery = &sQuery | %This.queryParams.GetNameByIndex(&nCnt) | "=" | EncodeURLForQueryString(&arrQueryValue [&nCnt]);
      End-If;
   End-For;
   
   If All(&sQuery) Then
      &sQuery = "?" | &sQuery;
   End-If;
   
   %This.debugMessage("Query String " | &sQuery);
   
   Return &sQuery;
end-method;

method isProd
   /+ Returns Boolean +/
   Return (Upper(%DbName) = "PROD" Or
      Upper(%DbName) = "PRD")
end-method;

method isBase64Encoded
   /+ &inStr as String +/
   /+ Returns Boolean +/
   Local JavaObject &joBase64Pattern = GetJavaClass("java.util.regex.Pattern").compile("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$");
   Return &joBase64Pattern.matcher(CreateJavaObject("java.lang.String", &inStr)).find();
end-method;

method debugMessage
   /+ &sInMsg as String +/
   If %This.Debug Then
      MessageBox(0, "", 0, 0, "*** DEBUG MESSAGE : %1 ", &sInMsg);
   End-If;
end-method;