create or replace PACKAGE BODY CT_MRDS.WORKFLOW_MANAGER
IS
 
   FUNCTION INIT_WORKFLOW(pServiceName IN VARCHAR2, pWorkflowRunId IN VARCHAR2, pWorkflowName in VARCHAR2)
   RETURN NUMBER
   IS
      vWorkflowHistoryKey NUMBER;
   BEGIN
      vWorkflowHistoryKey := A_WORKFLOW_HISTORY_KEY_SEQ.NEXTVAL;
      INSERT INTO CT_MRDS.A_WORKFLOW_HISTORY (SERVICE_NAME, A_WORKFLOW_HISTORY_KEY, ORCHESTRATION_RUN_ID,
                                              WORKFLOW_NAME, WORKFLOW_START, WORKFLOW_SUCCESSFUL)
                                      VALUES (pServiceName, vWorkflowHistoryKey, pWorkflowRunId,
                                              pWorkflowName, SYSTIMESTAMP, vpRunningStatus);

      return vWorkflowHistoryKey;

   END INIT_WORKFLOW;


   --
   -- Overload without service name for backward compatability, to be cleaned up later
   --
   PROCEDURE FINALISE_WORKFLOW(pWorkflowHistoryKey IN NUMBER, pWorkflowStatus IN VARCHAR2)
   IS
   BEGIN
      FINALISE_WORKFLOW(pWorkflowHistoryKey, NULL, pWorkflowStatus);
   END;

   PROCEDURE FINALISE_WORKFLOW(pWorkflowHistoryKey IN NUMBER, pServiceName IN VARCHAR2, pWorkflowStatus IN VARCHAR2)
   IS
   BEGIN
      UPDATE CT_MRDS.A_WORKFLOW_HISTORY SET WORKFLOW_SUCCESSFUL = pWorkflowStatus,
                                            WORKFLOW_END = SYSTIMESTAMP
                                  WHERE A_WORKFLOW_HISTORY_KEY = pWorkflowHistoryKey
                                    AND SERVICE_NAME = NVL(pServiceName,SERVICE_NAME);
   END FINALISE_WORKFLOW;


   FUNCTION INIT_TASK(pTaskRunId IN VARCHAR2, pTaskName in VARCHAR2, pWorkflowHistoryKey IN NUMBER)
   RETURN NUMBER
   IS
      vTaskHistoryKey NUMBER;
   BEGIN
      vTaskHistoryKey := A_TASK_HISTORY_KEY_SEQ.NEXTVAL;
      INSERT INTO CT_MRDS.A_TASK_HISTORY (A_TASK_HISTORY_KEY, TASK_RUN_ID, A_WORKFLOW_HISTORY_KEY,
                                              TASK_NAME, TASK_START, TASK_SUCCESSFUL)
                                      VALUES (vTaskHistoryKey, pTaskRunId, pWorkflowHistoryKey,
                                              pTaskName, SYSTIMESTAMP, vpRunningStatus);

      return vTaskHistoryKey;

   END INIT_TASK;


   PROCEDURE FINALISE_TASK(pTaskHistoryKey IN NUMBER, pTaskStatus IN VARCHAR2)
   IS
   BEGIN
      UPDATE CT_MRDS.A_TASK_HISTORY SET TASK_SUCCESSFUL = pTaskStatus,
                                            TASK_END = SYSTIMESTAMP
                                  WHERE A_TASK_HISTORY_KEY = pTaskHistoryKey;
   END FINALISE_TASK;

   -- Internal helper function without COMMIT for use within other functions
   FUNCTION STORE_TASK_SOURCE_INFO_INTERNAL(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, pNumRows IN NUMBER)
   RETURN NUMBER
   IS
      vTaskHistorySourceKey NUMBER;
   BEGIN
      vTaskHistorySourceKey := A_TASK_HISTORY_SOURCE_KEY_SEQ.NEXTVAL;
      INSERT INTO CT_MRDS.A_TASK_HISTORY_SOURCE (A_TASK_HISTORY_SOURCE_KEY, A_TASK_HISTORY_KEY,
                                                 SOURCE_NAME, ROW_COUNT)
                                         VALUES (vTaskHistorySourceKey, pTaskHistoryKey,
                                                 pSourceName, pNumRows);
      RETURN vTaskHistorySourceKey;
   END;

   FUNCTION STORE_TASK_SOURCE_INFO(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2, pNumRows IN NUMBER)
   RETURN NUMBER
   IS
      vTaskHistorySourceKey NUMBER;
   BEGIN
      vTaskHistorySourceKey := STORE_TASK_SOURCE_INFO_INTERNAL(pTaskHistoryKey, pSourceName, pNumRows);
      COMMIT;
      RETURN vTaskHistorySourceKey;
   END;

   -- Internal helper function without COMMIT for use within other functions
   FUNCTION STORE_TASK_TARGET_INFO_INTERNAL(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2,
                                           pNumRowsApplied IN NUMBER, pNumRowsRejected IN NUMBER,
                                           pLoadSuccessful IN VARCHAR2, pServiceName IN VARCHAR2)
   RETURN NUMBER
   IS
      vTaskHistoryTargetKey NUMBER;
   BEGIN
      vTaskHistoryTargetKey := A_TASK_HISTORY_TARGET_KEY_SEQ.NEXTVAL;
      INSERT INTO CT_MRDS.A_TASK_HISTORY_TARGET (A_TASK_HISTORY_TARGET_KEY, A_TASK_HISTORY_KEY,
                                                 TARGET_NAME, ROW_COUNT_APPLIED, ROW_COUNT_REJECTED,
                                                 LOAD_SUCCESSFUL, SERVICE_NAME)
                                         VALUES (vTaskHistoryTargetKey, pTaskHistoryKey,
                                                 pSourceName, pNumRowsApplied, pNumRowsRejected,
                                                 pLoadSuccessful, pServiceName);
      RETURN vTaskHistoryTargetKey;
   END;

   FUNCTION STORE_TASK_TARGET_INFO(pTaskHistoryKey IN NUMBER, pSourceName IN VARCHAR2,
                                   pNumRowsApplied IN NUMBER, pNumRowsRejected IN NUMBER,
                                   pLoadSuccessful IN VARCHAR2, pServiceName IN VARCHAR2)
   RETURN NUMBER
   IS
      vTaskHistoryTargetKey NUMBER;
   BEGIN
      vTaskHistoryTargetKey := STORE_TASK_TARGET_INFO_INTERNAL(
         pTaskHistoryKey, pSourceName, pNumRowsApplied,
         pNumRowsRejected, pLoadSuccessful, pServiceName
      );
      COMMIT;
      RETURN vTaskHistoryTargetKey;
   END;

   FUNCTION FINALISE_TASK_WITH_TARGET_INFO(pTaskHistoryKey IN NUMBER, pTaskStatus IN VARCHAR2,
                                          pTargetName IN VARCHAR2, pNumRowsApplied IN NUMBER,
                                          pNumRowsRejected IN NUMBER, pLoadSuccessful IN VARCHAR2,
                                          pServiceName IN VARCHAR2)
   RETURN NUMBER
   IS
      vTaskHistoryTargetKey NUMBER;
   BEGIN
      -- Store target information using internal function (without COMMIT)
      vTaskHistoryTargetKey := STORE_TASK_TARGET_INFO_INTERNAL(
         pTaskHistoryKey => pTaskHistoryKey,
         pSourceName => pTargetName,
         pNumRowsApplied => pNumRowsApplied,
         pNumRowsRejected => pNumRowsRejected,
         pLoadSuccessful => pLoadSuccessful,
         pServiceName => pServiceName
      );

      -- Finalize the task using existing procedure (no COMMIT in procedure)
      FINALISE_TASK(pTaskHistoryKey, pTaskStatus);

      -- Single COMMIT for the entire atomic operation
      COMMIT;

      RETURN vTaskHistoryTargetKey;
   END;

   PROCEDURE SET_WORKFLOW_PROPERTY(
       pWorkflowHistoryKey IN NUMBER
      ,pServiceName        IN VARCHAR2
      ,pProperty           IN VARCHAR2
      ,pValue              IN VARCHAR2
   ) IS
   BEGIN
      INSERT INTO CT_MRDS.A_WORKFLOW_HISTORY_PROPERTY (A_WORKFLOW_HISTORY_KEY, SERVICE_NAME, PROPERTY, VALUE)
                                               VALUES (pWorkflowHistoryKey, pServiceName, pProperty, pValue);
   END;

   FUNCTION GET_WORKFLOW_PROPERTY(
       pWorkflowHistoryKey IN NUMBER
      ,pServiceName        IN VARCHAR2
      ,pProperty           IN VARCHAR2
   ) RETURN VARCHAR2
   IS
      vValue CT_MRDS.A_WORKFLOW_HISTORY_PROPERTY.VALUE%TYPE;
   BEGIN
      SELECT VALUE
        INTO vValue
        FROM CT_MRDS.A_WORKFLOW_HISTORY_PROPERTY
       WHERE A_WORKFLOW_HISTORY_KEY = pWorkflowHistoryKey
         AND SERVICE_NAME = pServiceName
         AND PROPERTY = pProperty;

      RETURN vValue;
   END;

   ----------------------------------------------------------------------------------------------------
   -- PACKAGE VERSION MANAGEMENT FUNCTIONS IMPLEMENTATION
   ----------------------------------------------------------------------------------------------------

   FUNCTION GET_VERSION
   RETURN VARCHAR2
   IS
   BEGIN
      RETURN PACKAGE_VERSION;
   END GET_VERSION;

   ----------------------------------------------------------------------------------------------------

   FUNCTION GET_BUILD_INFO
   RETURN VARCHAR2
   IS
   BEGIN
      RETURN ENV_MANAGER.GET_PACKAGE_VERSION_INFO(
         pPackageName => 'WORKFLOW_MANAGER',
         pVersion => PACKAGE_VERSION,
         pBuildDate => PACKAGE_BUILD_DATE,
         pAuthor => PACKAGE_AUTHOR
      );
   END GET_BUILD_INFO;

   ----------------------------------------------------------------------------------------------------

   FUNCTION GET_VERSION_HISTORY
   RETURN VARCHAR2
   IS
   BEGIN
      RETURN ENV_MANAGER.FORMAT_VERSION_HISTORY(
         pPackageName => 'WORKFLOW_MANAGER',
         pVersionHistory => VERSION_HISTORY
      );
   END GET_VERSION_HISTORY;

   ----------------------------------------------------------------------------------------------------

END WORKFLOW_MANAGER;
