Function Reactors_API(@API)
/***********************************************************************************************************************

    This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
    permission from SRP Computer Solutions, Inc.

    Name        :   Reactors_API

    Description :   API logic for the Reactors resource.

    Notes       :   All web APIs should include the API_SETUP insert. This will provide several useful variables:

                        HTTPMethod              - The HTTP Method (Verb) submitted by the client (e.g., GET, POST, etc.)
                        APIURL                  - The URL for the API entry point (e.g., api.mysite.com/v1).
                        FullEndpointURL         - The URL submitted by the client, including query params.
                        FullEndpointURLNoQuery  - The URL submitted by the client, excluding query params.
                        EndpointSegment         - The URL endpoint segment.
                        ParentURL               - The URL path preceeding the current endpoint.
                        CurrentAPI              - The name of this stored procedure.

    Parameters  :
        API             [in] -- Web API to process. Format is [APIPattern].[HTTPMethod]:
                                    - APIPattern must follow this structure Reactors[.ID.[<Property>]]
                                    - HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc.
                                Examples:
                                    - Reactors.POST
                                    - Reactors.ID.PUT
                                    - Reactors.ID.firstName.GET
        Response       [out] -- Response to be sent back to the Controller (HTTP_MCP) or requesting procedure. Web API
                                services do not rely upon anything being returned in the response. This is what the
                                various services like SetResponseBody and SetResponseStatus services are for. A response
                                value is only helpful if the developers want to use it for debug purposes.

    History     :   (Date, Initials, Notes)
        07/08/22    xxx     Original programmer.

***********************************************************************************************************************/

#pragma precomp SRP_PreCompiler

$insert APP_INSERTS
$insert API_SETUP
$insert HTTP_INSERTS
$insert REACT_MODE_NG_EQUATES

Declare function   OI_Wizard_Services, Reactor_Modes_Services, Reactor_Services, SRP_JSON, MemberOf
Declare subroutine OI_Wizard_Services, Database_Services

GoToAPI else
    // The specific resource endpoint doesn't have a API handler yet.
    HTTP_Services('SetResponseStatus', 204, 'This is a valid endpoint but a web API handler has not yet been created.')
end

Return Response OR ''


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Endpoint Handlers
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


// Endpoint to get all or a range of reactor objects
API Reactors.HEAD
API Reactors.GET
    
    // Return an array of reactor objects
    // Look for the sessionID in the cookie
    Cookies = HTTP_Services('GetHTTPCookie')
    For each Cookie in Cookies using ';'
        Key = Field(Cookie, '=', 1)
        If Key EQ 'sessionID' then
            OIWizardID = Field(Cookie, '=', 2)
        end
    Next Cookie
    If Assigned(OIWizardID) then
        // Call validate session to extend session expiry
        OI_Wizard_Services('ValidateSession', OIWizardID)
        CurrUser = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
    end else
        CurrUser = ''
    end

    StatusCode = 200
    GoSub CreateHALCollection
    
end api


// Endpoint to get a reactor object
API Reactors.ID.GET

    // Return a reactor object
    ReactorNo = EndpointSegment
    If ReactorNo then
        // Look for the sessionID in the cookie
        Cookies = HTTP_Services('GetHTTPCookie')
        For each Cookie in Cookies using ';'
            Key = Field(Cookie, '=', 1)
            If Key EQ 'sessionID' then
                OIWizardID = Field(Cookie, '=', 2)
            end
        Next Cookie
        If Assigned(OIWizardID) then
            // Call validate session to extend session expiry
            OI_Wizard_Services('ValidateSession', OIWizardID)
            CurrUser = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
        end else
            CurrUser = ''
        end

        StatusCode = 200
        GoSub CreateHALItem
    end
    
end api


API Reactors.ID.PATCH
    
    // Update reactor reactor and return updated reactor object
    ReactorNo = EndpointSegment
    If ReactorNo then
        // Look for the sessionID in the cookie
        Cookies = HTTP_Services('GetHTTPCookie')
        For each Cookie in Cookies using ';'
            Key = Field(Cookie, '=', 1)
            If Key EQ 'sessionID' then
                OIWizardID = Field(Cookie, '=', 2)
            end
        Next Cookie
        
        ValidSession = OI_Wizard_Services('ValidateSession', OIWizardID)
        
        If ValidSession then
            // Check if payload has the required information to update a field in the reactors record
            Body = HTTP_Services('GetHTTPPostString')
            If Body NE '' then
                // The POST string will have been encoded so use percent (URL) decoding.
                JSON          = HTTP_Services('DecodePercentString', Body)
                hJSON         = ''
                ParseResponse = SRP_JSON(hJSON, 'PARSE', JSON)
                If (ParseResponse EQ '') then
                    LSLUser = Xlate('OI_WIZARD', OIWizardID, 'EMPLOYEE_ID', 'X')
                    ! Todo: Insert table & column level read/write checks (e.g. Does User123 has write access to 0311_ACTIVE column?)
                    ! Perhaps cycle through JSON properties passed in or read a table rights record to get a list of fields they can update.
                    //If MemberOf(LSLUser, 'OI_ADMIN') then 
                        // User has rights to update this resource
                        KeyID     = ReactorNo
                        NewRecord = Reactor_Services('ConvertJSONToRecord', KeyID, JSON)
                        If Error_Services('NoError') then
                            Database_Services('WriteDataRow', 'REACTOR', KeyID, NewRecord)
                            If Error_Services('NoError') then
                                StatusCode  = 200
                                Message     = 'Reactor Updated'
                                GoSub CreateHalItem
                            end else
                                HTTP_Services('SetResponseStatus', 500, Error_Services('GetMessage'))
                            end
                        end else
                            HTTP_Services('SetResponseStatus', 400, Error_Services('GetMessage'))
                        end
                    //end else
                        
                    //end
                    SRP_JSON(hJSON, 'Release')
                end else
                    // Error parsing JSON
                    HTTP_Services('SetResponseStatus', 400, 'Unable to parse the JSON data from the request.')
                end
            end else
                // No JSON payload sent with request
                HTTP_Services('SetResponseStatus', 400, 'JSON object is missing in the body of the request.')
            end
        end else
            HTTP_Services('SetResponseStatus', 401, 'Invalid session. Reauthentication required.')
        end
    end
    
end api


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Internal GoSubs
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//----------------------------------------------------------------------------------------------------------------------
// CreateHALItem
//
// Creates a HAL+JSON object based on the OpenInsight data row representation.
//----------------------------------------------------------------------------------------------------------------------
CreateHALItem:
    
    ReactorJSON = Reactor_Services('ConvertRecordToJSON', ReactorNo, FullEndpointURL, CurrUser)

    If Error_Services('NoError') then
        HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
        HTTP_Services('SetResponseBody', ReactorJSON, False$, 'application/hal+json')
        If Assigned(Message) then
            HTTP_Services('SetResponseStatus', StatusCode, Message)
        end else
            HTTP_Services('SetResponseStatus', StatusCode)
        end
    end else
        Message = Error_Services('GetMessage')          
        HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
    end

return


//----------------------------------------------------------------------------------------------------------------------
// CreateHALCollection
//
// Creates a HAL+JSON object based on OpenInsight data row representations.
//----------------------------------------------------------------------------------------------------------------------
CreateHALCollection:
    
    JSONCollection  = ''
    Abort           = False$
    ReactorList     = Reactor_Services('GetReactorNumbers')
    hJSONCollection = ''
    If SRP_JSON(hJSONCollection, 'New', 'Object') then
    	hReactorArray = ''
        If SRP_JSON(hReactorArray, 'New', 'Array') then
            For each ReactorNo in ReactorList using @FM setting fPos
                ReactorJSON = Reactor_Services('ConvertRecordToJSON', ReactorNo, FullEndpointURL:'/':ReactorNo, CurrUser, False$)
                If Error_Services('NoError') then
                	hReactor = ''
                    If (SRP_JSON(hReactor, 'Parse', ReactorJSON) EQ '') then
                        SRP_JSON(hReactorArray, 'Add', hReactor)
                        SRP_JSON(hReactor, 'Release')
                    end
                end else
                    Abort   = True$
                end
            Until Abort
            Next ReactorNo
            If Abort EQ False$ then
                SRP_JSON(hJSONCollection, 'Set', 'reactors', hReactorArray)
            end
            SRP_JSON(hReactorArray, 'Release')
        end
        JSONCollection = SRP_JSON(hJSONCollection, 'Stringify', 'Styled')
        SRP_JSON(hJSONCollection, 'Release')
    end
    
    If Error_Services('NoError') then
        HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
        HTTP_Services('SetResponseBody', JSONCollection, False$, 'application/hal+json')
        If Assigned(Message) then
            HTTP_Services('SetResponseStatus', StatusCode, Message)
        end else
            HTTP_Services('SetResponseStatus', StatusCode)
        end
    end else
        Message = Error_Services('GetMessage')          
        HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
    end

return
