 /*************************************************************/
 /* Copyright (c) 2012 by Progress Software Corporation.      */
 /*                                                           */
 /* All rights reserved.  No part of this program or document */
 /* may be  reproduced in  any form  or by  any means without */
 /* permission in writing from Progress Software Corporation. */
 /*************************************************************/
 /*------------------------------------------------------------------------
    File        : RestRequestInfo
    Purpose     : 
    Syntax      : 
    Description : 
    Author(s)   : hdaniels
    Created     : Thu Mar 15 14:40:57 EDT 2012
    Notes       : 
  ----------------------------------------------------------------------*/

using Progress.Lang.* from propath.
using Progress.Json.JsonParser from propath.
using Progress.Json.ObjectModel.* from propath.
using OpenEdge.DataAdmin.Lang.WebUtil from propath.
using OpenEdge.DataAdmin.Rest.IRestRequestInfo from propath.

routine-level on error undo, throw.

class OpenEdge.DataAdmin.Rest.RestRequestInfo implements IRestRequestInfo: 
    /** request URL */
    define public property Url        as char no-undo get. private set.
    
    /** URL method - POST, PUT, GET, DELETE */
    define public property Method     as char no-undo get. private set.
    
    /**  path for files  */
    define protected property Path     as char no-undo get.
        set(ppath as char):
            define variable i as integer no-undo.
            i = maximum(r-index(ppath,"~\"),r-index(ppath,"/")).
            if length(ppath) > i  then
            do:
                ppath = ppath 
                     + if r-index(ppath,"~\") = i then "~\" else "/".
            end.
            Path = ppath. 
        end.
    
    /** the slash entry position of the the connections collection in the URL */
    define public property ConnectionsPos as int no-undo init 3 get. set.
 
    /** Request body - json    */
    define public property FileName     as char no-undo get. private set.
    
    /** Log file for asynch request   */
    define public property LogFileName    as char no-undo 
        get():
            if LogFileName = "" then 
                return StripFileExtension(FileName) + ".log".
            return LogFileName.  
        end.  
        private set.
    
    /** app specifc status output  */
    define public property StatusFileName as char no-undo get. private set.
    
    /** Request response file. HTTP status header. json body if not asynch   */
    define public property OutFileName    as char no-undo 
        get():
            define variable cName as character no-undo.
            if OutFileName = "" then
            do: 
                if GetFileExtension(FileName) = "json" then
                    cName = StripFileExtension(FileName) + "_out.json".
                else
                    cName = StripFileExtension(FileName) + ".json".
                if cname = StatusFileName then
                do:
                    cName = StripFileExtension(cName) + "2.json".
                end.
                return cName.             
            end.
            return OutFileName.  
        end.  
        private set.
    
    /** a file to upload by the app - for example .df */
    define property UploadFileName as char no-undo get. private set.
   
    /** a file that will be generated by the app - for example .p */
    define property DownloadFileName as char no-undo get. private set.
    
    /** error file - "expected" errors - return OutFileName as default */
    define property ErrorFileName as char no-undo 
        get():
            if ErrorFileName = "" then 
                return OutFileName.
            return ErrorFileName.  
        end.  
        private set.
    
    /** rest collection  - the first   */
    define public property Collection     as char no-undo 
        get():
            define variable cColl as character no-undo.
            define variable i as integer no-undo.
            i = num-entries(URL,"/").
            if i >= ConnectionsPos and i le ConnectionsPos + 1 then 
                cColl = entry(ConnectionsPos,URL,"/"). 
            else if i >= ConnectionsPos + 2 then
                cColl = entry(ConnectionsPos + 2,URL,"/"). 
            if cColl > "" then
                return entry(1,cColl,"?").
            return "".   
        end. 
    
    /** capture file - output to in batch mode - unexpected errors  */
    define property CaptureFileName as char no-undo 
        get():
            define variable cFile as character no-undo.
            if CaptureFileName = "" then
            do:
                if method > "" and collection > "" then
                do:
                   cFile = method + "_" + Collection + ".log".
                end. 
                if cFile = "" then
                    cFile = "rest.log".
                return cFile.    
            end. 
            return CaptureFileName. 
        end. 
        private set.
    
    /** connection  -  db connection   */
    define public property Connection as char no-undo 
       get():
           if connection =  "" then
           do:
               if num-entries(URL,"/") > 3 then
                  return entry(4,URL,"/"). 
           end.
           return connection.   
       end.
       private set.
    
    /** run procedure    */
    define public property ProcedureName as char no-undo 
       get():
           return "darest/" 
                  + lc(Method + "_" + Collection + ".p").
    
       end.  

    /** log status info for load/dump- time interval in milliseconds */
    define public property StatusInterval as int no-undo get. private set. 
    
    constructor RestRequestInfo( ):
        super().
    end method.  
    
     /** initialize from json file */
    method void InitFromJSONFile(pcFileName as char):
        ReadJson(pcFileName).
    end method.  
          
    /** initialize from json object */
    method void InitFromJSON(pcPath as char,pJson as JsonObject):  
        Path = pcPath.
        ReadRequest(pjson).
    end method.  
    
    /* returns json object from the json file*/
    method protected void ReadJson  (pcFile as char):
        define variable parser as ObjectModelParser no-undo.
        define variable dummy as character no-undo.
        define variable json as JsonObject no-undo.
        file-info:file-name = pcfile.
        run prodict/misc/osprefix.p(file-info:pathname,output Path,output dummy).
        parser = new ObjectModelParser().
        json = cast(parser:ParseFile(pcfile),JsonObject).
        ReadRequest(json).      
    end method.
    
    method protected void ReadRequest(pJson as JsonObject).
        if pJson:Has("request") then
             ReadProperties(pJson:GetJsonObject("request")).
    end method.
    
    method protected character GetFullPathName(pJson as JSonObject,pcProp as char).
        define variable cName as character no-undo.
        cName = pJson:GetCharacter(pcProp). 
        if index(cName,":") > 0 
        or cName begins("/") 
        or cName begins("~\") then
            return cName.
        else 
            return Path + cName.        
    end method.
     
    method protected void ReadProperties(pJson as JSONObject).
        if pJson:Has("url") then
            Url =  pJson:GetCharacter("url").
        if pJson:Has("method") then
            Method =  pJson:GetCharacter("method").
  
        if pJson:Has("connection") then
            Connection = pJson:GetCharacter("connection").

        if pJson:Has("fileName") then
            FileName = GetFullPathName(pJson,"fileName").
        if pJson:Has("logFileName") then
            LogFileName = GetFullPathName(pJson,"logFileName").
        if pJson:Has("outFileName") then
            OutFileName = GetFullPathName(pJson,"outFileName").
        if pJson:Has("statusFileName") then
            StatusFileName = GetFullPathName(pJson,"statusFileName").
        if pJson:Has("uploadFileName") then
            UploadFileName = GetFullPathName(pJson,"uploadFileName").
        if pJson:Has("downloadFileName") then
            DownloadFileName = GetFullPathName(pJson,"downloadFileName").
        if pJson:Has("captureFileName") then
            CaptureFileName = GetFullPathName(pJson,"captureFileName").
        if pJson:Has("errorFileName") then
            ErrorFileName = GetFullPathName(pJson,"errorFileName").
        if pJson:Has("statusInterval") then
            StatusInterval = pJson:GetInteger("statusInterval").
            
    end.
    
    method protected char GetFileExtension(pcFile as char):
        define variable i as integer no-undo.
        i = num-entries(pcfile,".").
        if i > 1 then
            return entry(i,pcfile,".").
        else return "".    
    end method. 
    
    method protected char StripFileExtension(pcFile as char):
        define variable i as integer no-undo.
        i = num-entries(pcfile,".").
        if i > 1 then
        do:
            entry(i,pcfile,".") = "".
            pcfile = right-trim(pcfile,".").
        end.   
        return pcfile.    
    end method. 
      
end class.