--MARS-770

set verify off
SET serveroutput ON
--SET TIMING ON
whenever sqlerror exit sql.sqlcode rollback;

column owner format a15
column object_name format a30
column spoolname new_value spoolname 

select 'install_package_MarsGeneralRelease_MARS770_packages_1_' || name || '_' ||to_char(sysdate,'YYYYMMDD_HH24MISS')||'.log' spoolname from v$pdbs;
spool '&spoolname'


prompt ##### started at time #####
select systimestamp from dual;
prompt ##### database name #####
select name pdb_name from v$pdbs;

--set echo on
--=============================================================================================================================
-- start install --MARS-770 payload CT_MRDS.ENV_MANAGER package
--=============================================================================================================================

CREATE OR REPLACE EDITIONABLE PACKAGE "CT_MRDS"."ENV_MANAGER"
AUTHID CURRENT_USER
AS
   /**
      * General comment for package: Please put comments for functions and procedures as shown in below example.
      * It is a standard.
      * The structure of comment is used by GET_PACKAGE_DOCUMENTATION function
      * which returns documentation text for confluence page (to Copy-Paste it).
   **/

   -- Example comment:
         /**
            * @name     EX_PROCEDURE_NAME
            * @desc     Procedure description
            * @example  select ENV_MANAGER.EX_PROCEDURE_NAME(pParameter => 129) from dual;
            * @ex_rslt  Example Result
         **/

   TYPE Error_Record IS RECORD (
      code PLS_INTEGER,
      message VARCHAR2(4000)
   );

   TYPE tErrorList IS TABLE OF Error_Record INDEX BY PLS_INTEGER;  

   Errors               tErrorList;


   guid                 VARCHAR2(32);
   gvEnv                VARCHAR2(200);
   gvUsername           VARCHAR2(128);
   gvOsuser             VARCHAR2(128);
   gvMachine            VARCHAR2(64);
   gvModule             VARCHAR2(64);

   gvNameSpace          VARCHAR2(200);
   gvRegion             VARCHAR2(200);
   gvDataBucketName     VARCHAR2(200);
   gvInboxBucketName    VARCHAR2(200);
   gvHistoryBucketName  VARCHAR2(200);
   gvDataBucketUri      VARCHAR2(200);
   gvInboxBucketUri     VARCHAR2(200);
   gvHistoryBucketUri   VARCHAR2(200);
   gvCredentialName     VARCHAR2(200);

   -- Overwritten by variable "LoggingEnabled" in  A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
   gvLoggingEnabled     VARCHAR2(3)   := 'ON';    -- 'ON' or 'OFF'

   -- Overwritten by variable "MinLogLevel" in  A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
   -- Possible values: DEBUG ,INFO ,WARNING ,ERROR
   gvMinLogLevel        VARCHAR2(10)  := 'DEBUG';  

   -- Overwritten by variable "DefaultDateFormat" in  A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
   gvDefaultDateFormat  VARCHAR2(200) := 'DD/MM/YYYY HH24:MI:SS';

   -- Overwritten by variable "ConsoleLoggingEnabled" in  A_FILE_MANAGER_CONFIG.CONFIG_VARIABLE table
   gvConsoleLoggingEnabled VARCHAR2(3) := 'ON';    -- 'ON' or 'OFF'

   cgBL       CONSTANT  VARCHAR2(2)   := CHR(13)||CHR(10);

   vgSourceFileConfigKey   PLS_INTEGER;  

   vgMsgTmp                 VARCHAR2(32000);
   --Exceptions
    ERR_EMPTY_FILEURI_AND_RECKEY          EXCEPTION;
   CODE_EMPTY_FILEURI_AND_RECKEY          CONSTANT PLS_INTEGER := -20001;
    MSG_EMPTY_FILEURI_AND_RECKEY_C        VARCHAR2(4000)       := 'Either pFileUri or pSourceFileReceivedKey must be not null';
    MSG_EMPTY_FILEURI_AND_RECKEY          VARCHAR2(4000)       :=  MSG_EMPTY_FILEURI_AND_RECKEY_C;
   PRAGMA EXCEPTION_INIT( ERR_EMPTY_FILEURI_AND_RECKEY
                        ,CODE_EMPTY_FILEURI_AND_RECKEY);


    ERR_NO_CONFIG_MATCH_FOR_FILEURI       EXCEPTION;
   CODE_NO_CONFIG_MATCH_FOR_FILEURI       CONSTANT PLS_INTEGER := -20002;
    MSG_NO_CONFIG_MATCH_FOR_FILEURI_C     VARCHAR2(4000)       := 'No match for source file in A_SOURCE_FILE_CONFIG table'
                                               ||cgBL||'           The file provided in parameter: pFileUri does not have '
                                               ||cgBL||'           coresponding configuration in A_SOURCE_FILE_CONFIG table';
    MSG_NO_CONFIG_MATCH_FOR_FILEURI       VARCHAR2(4000)       :=  MSG_NO_CONFIG_MATCH_FOR_FILEURI_C;
   PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH_FOR_FILEURI
                        ,CODE_NO_CONFIG_MATCH_FOR_FILEURI);

    ERR_MULTIPLE_MATCH_FOR_SRCFILE        EXCEPTION;
   CODE_MULTIPLE_MATCH_FOR_SRCFILE        CONSTANT PLS_INTEGER := -20003;
    MSG_MULTIPLE_MATCH_FOR_SRCFILE_C      VARCHAR2(4000)       := 'Multiple match for source file in A_SOURCE_FILE_CONFIG table';
    MSG_MULTIPLE_MATCH_FOR_SRCFILE        VARCHAR2(4000)       :=  MSG_MULTIPLE_MATCH_FOR_SRCFILE_C;
   PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_MATCH_FOR_SRCFILE
                        ,CODE_MULTIPLE_MATCH_FOR_SRCFILE);

    ERR_MISSING_COLUMN_DATE_FORMAT        EXCEPTION;
   CODE_MISSING_COLUMN_DATE_FORMAT        CONSTANT PLS_INTEGER  := -20004;
    MSG_MISSING_COLUMN_DATE_FORMAT_C      VARCHAR2(4000)        := 'Missing entry in config table: A_COLUMN_DATE_FORMAT primary key(A_SOURCE_FILE_CONFIG_KEY, COLUMN_NAME)'
                                                ||cgBL||'           Remember: each column which data_type IN (''DATE'', ''TIMESTAMP'')'
                                                ||cgBL||'           should have DateFormat specified in A_COLUMN_DATE_FORMAT table '
                                                ||cgBL||'           for example: ''YYYY-MM-DD''';
    MSG_MISSING_COLUMN_DATE_FORMAT        VARCHAR2(4000)        :=  MSG_MISSING_COLUMN_DATE_FORMAT_C;
   PRAGMA EXCEPTION_INIT( ERR_MISSING_COLUMN_DATE_FORMAT
                        ,CODE_MISSING_COLUMN_DATE_FORMAT);

    ERR_MULTIPLE_COLUMN_DATE_FORMAT       EXCEPTION;
   CODE_MULTIPLE_COLUMN_DATE_FORMAT       CONSTANT PLS_INTEGER := -20005;
    MSG_MULTIPLE_COLUMN_DATE_FORMAT_C     VARCHAR2(4000)       := 'Multiple records for date format in A_COLUMN_DATE_FORMAT table'
                                               ||cgBL||'           There should be only one format specified for each DAT/TIMESTAMP column';
    MSG_MULTIPLE_COLUMN_DATE_FORMAT       VARCHAR2(4000)       :=  MSG_MULTIPLE_COLUMN_DATE_FORMAT_C;
   PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_COLUMN_DATE_FORMAT
                        ,CODE_MULTIPLE_COLUMN_DATE_FORMAT);


    ERR_DIDNT_GET_LOAD_OPERATION_ID       EXCEPTION;
   CODE_DIDNT_GET_LOAD_OPERATION_ID       CONSTANT PLS_INTEGER := -20006;
    MSG_DIDNT_GET_LOAD_OPERATION_ID_C     VARCHAR2(4000)       := 'Didnt get load operation id from external table validation';
    MSG_DIDNT_GET_LOAD_OPERATION_ID       VARCHAR2(4000)       :=  MSG_DIDNT_GET_LOAD_OPERATION_ID_C;
   PRAGMA EXCEPTION_INIT( ERR_DIDNT_GET_LOAD_OPERATION_ID
                        ,CODE_DIDNT_GET_LOAD_OPERATION_ID);

    ERR_NO_CONFIG_FOR_RECEIVED_FILE       EXCEPTION;
   CODE_NO_CONFIG_FOR_RECEIVED_FILE       CONSTANT PLS_INTEGER := -20007;
    MSG_NO_CONFIG_FOR_RECEIVED_FILE_C     VARCHAR2(4000)       := 'No match for received source file in A_SOURCE_FILE_CONFIG '
                                              ||cgBL||'            or missing data in A_SOURCE_FILE_RECEIVED table for provided pSourceFileReceivedKey parameter';
    MSG_NO_CONFIG_FOR_RECEIVED_FILE       VARCHAR2(4000)       :=  MSG_NO_CONFIG_FOR_RECEIVED_FILE_C;
   PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_FOR_RECEIVED_FILE
                        ,CODE_NO_CONFIG_FOR_RECEIVED_FILE);

    ERR_MULTI_CONFIG_FOR_RECEIVED_FILE    EXCEPTION;
   CODE_MULTI_CONFIG_FOR_RECEIVED_FILE    CONSTANT PLS_INTEGER := -20008;
    MSG_MULTI_CONFIG_FOR_RECEIVED_FILE_C  VARCHAR2(4000)       := 'Multiple matchs for received source file in A_SOURCE_FILE_CONFIG';
    MSG_MULTI_CONFIG_FOR_RECEIVED_FILE    VARCHAR2(4000)       :=  MSG_MULTI_CONFIG_FOR_RECEIVED_FILE_C;
   PRAGMA EXCEPTION_INIT( ERR_MULTI_CONFIG_FOR_RECEIVED_FILE
                        ,CODE_MULTI_CONFIG_FOR_RECEIVED_FILE);

    ERR_FILE_NOT_FOUND_ON_CLOUD           EXCEPTION;
   CODE_FILE_NOT_FOUND_ON_CLOUD           CONSTANT PLS_INTEGER := -20009;
    MSG_FILE_NOT_FOUND_ON_CLOUD_C         VARCHAR2(4000)       := 'File not found on the cloud';
    MSG_FILE_NOT_FOUND_ON_CLOUD           VARCHAR2(4000)       :=  MSG_FILE_NOT_FOUND_ON_CLOUD_C;
   PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_FOUND_ON_CLOUD
                        ,CODE_FILE_NOT_FOUND_ON_CLOUD);

    ERR_FILE_VALIDATION_FAILED            EXCEPTION;
   CODE_FILE_VALIDATION_FAILED            CONSTANT PLS_INTEGER := -20010;
    MSG_FILE_VALIDATION_FAILED_C          VARCHAR2(4000)       := 'File validation failed';
    MSG_FILE_VALIDATION_FAILED            VARCHAR2(4000)       :=  MSG_FILE_VALIDATION_FAILED_C;
   PRAGMA EXCEPTION_INIT( ERR_FILE_VALIDATION_FAILED
                        ,CODE_FILE_VALIDATION_FAILED);

    ERR_NO_CONFIG_MATCH                   EXCEPTION;
   CODE_NO_CONFIG_MATCH                   CONSTANT PLS_INTEGER := -20011;
    MSG_NO_CONFIG_MATCH_C                 VARCHAR2(4000)       := 'No match for specified parameters in A_SOURCE_FILE_CONFIG table';
    MSG_NO_CONFIG_MATCH                   VARCHAR2(4000)       :=  MSG_NO_CONFIG_MATCH_C;
   PRAGMA EXCEPTION_INIT( ERR_NO_CONFIG_MATCH
                        ,CODE_NO_CONFIG_MATCH);

    ERR_UNKNOWN_PREFIX                    EXCEPTION;
   CODE_UNKNOWN_PREFIX                    CONSTANT PLS_INTEGER := -20012;
    MSG_UNKNOWN_PREFIX_C                  VARCHAR2(4000)       := 'Unknown prefix';
    MSG_UNKNOWN_PREFIX                    VARCHAR2(4000)       :=  MSG_UNKNOWN_PREFIX_C;
   PRAGMA EXCEPTION_INIT( ERR_UNKNOWN_PREFIX
                        ,CODE_UNKNOWN_PREFIX);

    ERR_TABLE_NOT_EXISTS                  EXCEPTION;
   CODE_TABLE_NOT_EXISTS                  CONSTANT PLS_INTEGER := -20013;
    MSG_TABLE_NOT_EXISTS_C                VARCHAR2(4000)       := 'Table does not exist';
    MSG_TABLE_NOT_EXISTS                  VARCHAR2(4000)       :=  MSG_TABLE_NOT_EXISTS_C;
   PRAGMA EXCEPTION_INIT( ERR_TABLE_NOT_EXISTS
                        ,CODE_TABLE_NOT_EXISTS);

    ERR_COLUMN_NOT_EXISTS                 EXCEPTION;
   CODE_COLUMN_NOT_EXISTS                 CONSTANT PLS_INTEGER := -20014;
    MSG_COLUMN_NOT_EXISTS_C               VARCHAR2(4000)       := 'Column does not exist in table';
    MSG_COLUMN_NOT_EXISTS                 VARCHAR2(4000)       :=  MSG_COLUMN_NOT_EXISTS_C;
   PRAGMA EXCEPTION_INIT( ERR_COLUMN_NOT_EXISTS
                        ,CODE_COLUMN_NOT_EXISTS);

    ERR_UNSUPPORTED_DATA_TYPE             EXCEPTION;
   CODE_UNSUPPORTED_DATA_TYPE             CONSTANT PLS_INTEGER := -20015;
    MSG_UNSUPPORTED_DATA_TYPE_C           VARCHAR2(4000)       := 'Unsupported data type';
    MSG_UNSUPPORTED_DATA_TYPE             VARCHAR2(4000)       :=  MSG_UNSUPPORTED_DATA_TYPE_C;
   PRAGMA EXCEPTION_INIT( ERR_UNSUPPORTED_DATA_TYPE
                        ,CODE_UNSUPPORTED_DATA_TYPE);

    ERR_MISSING_SOURCE_KEY                EXCEPTION;
   CODE_MISSING_SOURCE_KEY                CONSTANT PLS_INTEGER := -20016;
    MSG_MISSING_SOURCE_KEY_C              VARCHAR2(4000)       := 'The Source was not found in parent table A_SOURCE';
    MSG_MISSING_SOURCE_KEY                VARCHAR2(4000)       :=  MSG_MISSING_SOURCE_KEY_C;
   PRAGMA EXCEPTION_INIT( ERR_MISSING_SOURCE_KEY
                        ,CODE_MISSING_SOURCE_KEY);

    ERR_NULL_SOURCE_FILE_CONFIG_KEY       EXCEPTION;
   CODE_NULL_SOURCE_FILE_CONFIG_KEY       CONSTANT PLS_INTEGER := -20017;
    MSG_NULL_SOURCE_FILE_CONFIG_KEY_C     VARCHAR2(4000)       := 'No entry in A_SOURCE_FILE_CONFIG table for specified A_SOURCE_FILE_CONFIG_KEY';
    MSG_NULL_SOURCE_FILE_CONFIG_KEY       VARCHAR2(4000)       :=  MSG_NULL_SOURCE_FILE_CONFIG_KEY_C;
   PRAGMA EXCEPTION_INIT( ERR_NULL_SOURCE_FILE_CONFIG_KEY
                        ,CODE_NULL_SOURCE_FILE_CONFIG_KEY);

    ERR_DUPLICATED_SOURCE_KEY             EXCEPTION;
   CODE_DUPLICATED_SOURCE_KEY             CONSTANT PLS_INTEGER := -20018;
    MSG_DUPLICATED_SOURCE_KEY_C           VARCHAR2(4000)       := 'The Source already exists in the A_SOURCE table';
    MSG_DUPLICATED_SOURCE_KEY             VARCHAR2(4000)       :=  MSG_DUPLICATED_SOURCE_KEY_C;
   PRAGMA EXCEPTION_INIT( ERR_DUPLICATED_SOURCE_KEY
                        ,CODE_DUPLICATED_SOURCE_KEY);

    ERR_MISSING_CONTAINER_CONFIG          EXCEPTION;
   CODE_MISSING_CONTAINER_CONFIG          CONSTANT PLS_INTEGER := -20019;
    MSG_MISSING_CONTAINER_CONFIG_C        VARCHAR2(4000)       := 'No match in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID';
    MSG_MISSING_CONTAINER_CONFIG          VARCHAR2(4000)       :=  MSG_MISSING_CONTAINER_CONFIG_C;
   PRAGMA EXCEPTION_INIT( ERR_MISSING_CONTAINER_CONFIG
                        ,CODE_MISSING_CONTAINER_CONFIG);

    ERR_MULTIPLE_CONTAINER_ENTRIES        EXCEPTION;
   CODE_MULTIPLE_CONTAINER_ENTRIES        CONSTANT PLS_INTEGER := -20020;
    MSG_MULTIPLE_CONTAINER_ENTRIES_C      VARCHAR2(4000)       := 'Multiple matches in A_SOURCE_FILE_CONFIG table where SOURCE_FILE_TYPE=''CONTAINER'' and specified SOURCE_FILE_ID';
    MSG_MULTIPLE_CONTAINER_ENTRIES        VARCHAR2(4000)       :=  MSG_MULTIPLE_CONTAINER_ENTRIES_C;
   PRAGMA EXCEPTION_INIT( ERR_MULTIPLE_CONTAINER_ENTRIES
                        ,CODE_MULTIPLE_CONTAINER_ENTRIES);

    ERR_WRONG_DESTINATION_PARAM           EXCEPTION;
   CODE_WRONG_DESTINATION_PARAM           CONSTANT PLS_INTEGER := -20021;
    MSG_WRONG_DESTINATION_PARAM_C         VARCHAR2(4000)       := 'Wrong destination parameter provided.';
    MSG_WRONG_DESTINATION_PARAM           VARCHAR2(4000)       :=  MSG_WRONG_DESTINATION_PARAM_C;
   PRAGMA EXCEPTION_INIT( ERR_WRONG_DESTINATION_PARAM
                        ,CODE_WRONG_DESTINATION_PARAM);

    ERR_FILE_NOT_EXISTS_ON_CLOUD          EXCEPTION;
   CODE_FILE_NOT_EXISTS_ON_CLOUD          CONSTANT PLS_INTEGER := -20022;
    MSG_FILE_NOT_EXISTS_ON_CLOUD_C        VARCHAR2(4000)       := 'File not exists on cloud.';
    MSG_FILE_NOT_EXISTS_ON_CLOUD          VARCHAR2(4000)       :=  MSG_FILE_NOT_EXISTS_ON_CLOUD_C;
   PRAGMA EXCEPTION_INIT( ERR_FILE_NOT_EXISTS_ON_CLOUD
                        ,CODE_FILE_NOT_EXISTS_ON_CLOUD);

    ERR_FILE_ALREADY_REGISTERED           EXCEPTION;
   CODE_FILE_ALREADY_REGISTERED           CONSTANT PLS_INTEGER := -20023;
    MSG_FILE_ALREADY_REGISTERED_C         VARCHAR2(4000)       := 'File already registered in A_SOURCE_FILE_RECEIVED table.';
    MSG_FILE_ALREADY_REGISTERED           VARCHAR2(4000)       :=  MSG_FILE_ALREADY_REGISTERED_C;
   PRAGMA EXCEPTION_INIT( ERR_FILE_ALREADY_REGISTERED
                        ,CODE_FILE_ALREADY_REGISTERED);

    ERR_WRONG_DATE_TIMESTAMP_FORMAT       EXCEPTION;
   CODE_WRONG_DATE_TIMESTAMP_FORMAT       CONSTANT PLS_INTEGER := -20024;
    MSG_WRONG_DATE_TIMESTAMP_FORMAT_C     VARCHAR2(4000)       := 'Provided DATE or TIMESTAMP format has errors (possible duplicated codes, ex: ''DD'').';
    MSG_WRONG_DATE_TIMESTAMP_FORMAT       VARCHAR2(4000)       :=  MSG_WRONG_DATE_TIMESTAMP_FORMAT_C;
   PRAGMA EXCEPTION_INIT( ERR_WRONG_DATE_TIMESTAMP_FORMAT
                        ,CODE_WRONG_DATE_TIMESTAMP_FORMAT);

    ERR_ENVIRONMENT_NOT_SET               EXCEPTION;
   CODE_ENVIRONMENT_NOT_SET               CONSTANT PLS_INTEGER := -20025;
    MSG_ENVIRONMENT_NOT_SET_C             VARCHAR2(4000)       := 'EnvironmentID not set'
                                                ||cgBL||'           Information about environment is needed to get proper configuration values.'
                                                ||cgBL||'           It can be set up in two different ways:'
                                                ||cgBL||'           1. Set it on session level:       execute DBMS_SESSION.SET_IDENTIFIER (client_id => ''dev'')'
                                                ||cgBL||'           2. Set it on configuration level: Insert into CT_MRDS.A_FILE_MANAGER_CONFIG (ENVIRONMENT_ID,CONFIG_VARIABLE,CONFIG_VARIABLE_VALUE) values (''default'',''environment_id'',''dev'')'
                                                ||cgBL||'           Session level setup (1.) takes precedence over configuration level one (2.)'
                                                  ;
    MSG_ENVIRONMENT_NOT_SET               VARCHAR2(4000)       :=  MSG_ENVIRONMENT_NOT_SET_C;
   PRAGMA EXCEPTION_INIT( ERR_ENVIRONMENT_NOT_SET
                        ,CODE_ENVIRONMENT_NOT_SET);


    ERR_CONFIG_VARIABLE_NOT_SET           EXCEPTION;
   CODE_CONFIG_VARIABLE_NOT_SET           CONSTANT PLS_INTEGER := -20026;
    MSG_CONFIG_VARIABLE_NOT_SET_C         VARCHAR2(4000)       := 'Missing configuration value in A_FILE_MANAGER_CONFIG';
    MSG_CONFIG_VARIABLE_NOT_SET           VARCHAR2(4000)       :=  MSG_CONFIG_VARIABLE_NOT_SET_C;
   PRAGMA EXCEPTION_INIT( ERR_CONFIG_VARIABLE_NOT_SET
                        ,CODE_CONFIG_VARIABLE_NOT_SET);

    ERR_NOT_INPUT_SOURCE_FILE_TYPE        EXCEPTION;
   CODE_NOT_INPUT_SOURCE_FILE_TYPE        CONSTANT PLS_INTEGER := -20027;
    MSG_NOT_INPUT_SOURCE_FILE_TYPE_C      VARCHAR2(4000)       := 'Historization can be executed only for A_SOURCE_FILE_CONFIG_KEY where SOURCE_FILE_TYPE=''INPUT''';
    MSG_NOT_INPUT_SOURCE_FILE_TYPE        VARCHAR2(4000)       :=  MSG_NOT_INPUT_SOURCE_FILE_TYPE_C;
   PRAGMA EXCEPTION_INIT( ERR_NOT_INPUT_SOURCE_FILE_TYPE
                        ,CODE_NOT_INPUT_SOURCE_FILE_TYPE);

    ERR_EXP_DATA_FOR_HIST_FAILED          EXCEPTION;
   CODE_EXP_DATA_FOR_HIST_FAILED          CONSTANT PLS_INTEGER := -20028;
    MSG_EXP_DATA_FOR_HIST_FAILED_C        VARCHAR2(4000)       := 'Export data for historization failed.';
    MSG_EXP_DATA_FOR_HIST_FAILED          VARCHAR2(4000)       :=  MSG_EXP_DATA_FOR_HIST_FAILED_C;
   PRAGMA EXCEPTION_INIT( ERR_EXP_DATA_FOR_HIST_FAILED
                        ,CODE_EXP_DATA_FOR_HIST_FAILED);

    ERR_RESTORE_FILE_FROM_TRASH           EXCEPTION;
   CODE_RESTORE_FILE_FROM_TRASH           CONSTANT PLS_INTEGER := -20029;
    MSG_RESTORE_FILE_FROM_TRASH_C         VARCHAR2(4000)       := 'Unexpected issues occured while historization process. Restoration of exported files failed.';
    MSG_RESTORE_FILE_FROM_TRASH           VARCHAR2(4000)       :=  MSG_RESTORE_FILE_FROM_TRASH_C;
   PRAGMA EXCEPTION_INIT( ERR_RESTORE_FILE_FROM_TRASH
                        ,CODE_RESTORE_FILE_FROM_TRASH);

    ERR_CHANGE_STAT_TO_HISTORISED_FAILED           EXCEPTION;
   CODE_CHANGE_STAT_TO_HISTORISED_FAILED           CONSTANT PLS_INTEGER := -20030;
    MSG_CHANGE_STAT_TO_HISTORISED_FAILED_C         VARCHAR2(4000)       := 'Failed to change file status to: HISTORISED in A_SOURCE_FILE_RECEIVED table.';
    MSG_CHANGE_STAT_TO_HISTORISED_FAILED           VARCHAR2(4000)       :=  MSG_CHANGE_STAT_TO_HISTORISED_FAILED_C;
   PRAGMA EXCEPTION_INIT( ERR_CHANGE_STAT_TO_HISTORISED_FAILED
                        ,CODE_CHANGE_STAT_TO_HISTORISED_FAILED);

    ERR_MOVE_FILE_TO_TRASH_FAILED          EXCEPTION;
   CODE_MOVE_FILE_TO_TRASH_FAILED          CONSTANT PLS_INTEGER := -20031;
    MSG_MOVE_FILE_TO_TRASH_FAILED_C        VARCHAR2(4000)       := 'FAILED to move file to TRASH before DROPPING it.';
    MSG_MOVE_FILE_TO_TRASH_FAILED          VARCHAR2(4000)       :=  MSG_MOVE_FILE_TO_TRASH_FAILED_C;
   PRAGMA EXCEPTION_INIT( ERR_MOVE_FILE_TO_TRASH_FAILED
                        ,CODE_MOVE_FILE_TO_TRASH_FAILED);

    ERR_DROP_EXPORTED_FILES_FAILED          EXCEPTION;
   CODE_DROP_EXPORTED_FILES_FAILED          CONSTANT PLS_INTEGER := -20032;
    MSG_DROP_EXPORTED_FILES_FAILED_C        VARCHAR2(4000)       := 'FAILED to move file to TRASH before DROPPING it.';
    MSG_DROP_EXPORTED_FILES_FAILED          VARCHAR2(4000)       :=  MSG_DROP_EXPORTED_FILES_FAILED_C;
   PRAGMA EXCEPTION_INIT( ERR_DROP_EXPORTED_FILES_FAILED
                        ,CODE_DROP_EXPORTED_FILES_FAILED);


    ERR_UNKNOWN                           EXCEPTION;
   CODE_UNKNOWN                           CONSTANT PLS_INTEGER := -20999;
    MSG_UNKNOWN_C                         VARCHAR2(4000)       := 'Unknown Error Occured';
    MSG_UNKNOWN                           VARCHAR2(4000)       :=  MSG_UNKNOWN_C;
   PRAGMA EXCEPTION_INIT( ERR_UNKNOWN
                        ,CODE_UNKNOWN);

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




   /**
      * @name     LOG_PROCESS_EVENT
      * @desc     Insert a new log record into A_PROCESS_LOG table.
      *           Also outputs to console if gvConsoleLoggingEnabled = 'ON'.
      *           Respects logging level configuration (gvMinLogLevel).
      * @example  ENV_MANAGER.LOG_PROCESS_EVENT('Process completed successfully', 'INFO', 'pParam1=value1');
      * @ex_rslt  Record inserted into A_PROCESS_LOG table and optionally displayed in console output
   **/
   PROCEDURE LOG_PROCESS_EVENT (
       pLogMessage   VARCHAR2
      ,pLogLevel     VARCHAR2 DEFAULT 'ERROR'
      ,pParameters   VARCHAR2 DEFAULT  NULL
      ,pProcessName  VARCHAR2 DEFAULT 'FILE_MANAGER'
   );



   /**
      * @name     INIT_ERRORS
      * @desc     Loads data into Errors array.
      *           Errors array is a list of Record(Error_Code, Error_Message) index by Error_Code.
      *           Called automatically during package initialization.
      * @example  Called automatically when package is first referenced
      * @ex_rslt  Errors array populated with all error codes and messages
   **/
   PROCEDURE INIT_ERRORS;



   /**
      * @name     GET_DEFAULT_ENV
      * @desc     It returns string with name of default environment.
      *           Return string is A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID value.
      * @example  select ENV_MANAGER.GET_DEFAULT_ENV() from dual;
      * @ex_rslt  dev
   **/
   FUNCTION GET_DEFAULT_ENV
   RETURN VARCHAR2;



   /**
      * @name     INIT_VARIABLES
      * @desc     For specified pEnv parameter (A_FILE_MANAGER_CONFIG.ENVIRONMENT_ID)
      *           Assign values to following global package variables:
      *           - gvNameSpace
      *           - gvRegion
      *           - gvCredentialName
      *           - gvInboxBucketName
      *           - gvDataBucketName
      *           - gvHistoryBucketName
      *           - gvInboxBucketUri
      *           - gvDataBucketUri
      *           - gvHistoryBucketUri
      *           - gvLoggingEnabled
      *           - gvMinLogLevel
      *           - gvDefaultDateFormat
      *           - gvConsoleLoggingEnabled
   **/
   PROCEDURE INIT_VARIABLES(
      pEnv VARCHAR2
   );



   /**
      * @name     GET_ERROR_MESSAGE
      * @desc     It returns string with error message for specified pCode (Error_Code).
      *           Error message is take from Errors Array loaded by INIT_ERRORS procedure
      * @example  select ENV_MANAGER.GET_ERROR_MESSAGE(pCode => -20009) from dual;
      * @ex_rslt  File not found on the cloud
   **/
   FUNCTION GET_ERROR_MESSAGE(
      pCode PLS_INTEGER
   ) RETURN VARCHAR2;



   /**
      * @name     GET_ERROR_STACK
      * @desc     It returns string with all possible error stack info.
      *           Error message is take from Errors Array loaded by INIT_ERRORS procedure
      * @example  
      *           select ENV_MANAGER.GET_ERROR_STACK(
      *                 pFormat                 => 'OUTPUT'
      *                ,pCode                   => -20009
      *                ,pSourceFileReceivedKey  => NULL)
      *           from dual
      * @ex_rslt  
      *           ------------------------------------------------------+
      *           Error Message:
      *           ORA-0000: normal, successful completion
      *           -------------------------------------------------------
      *           Error Stack:
      *           -------------------------------------------------------
      *           Error Backtrace:
      *           ------------------------------------------------------+
   **/
   FUNCTION GET_ERROR_STACK(
      pFormat  VARCHAR2
     ,pCode PLS_INTEGER
     ,pSourceFileReceivedKey CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL
   ) RETURN VARCHAR2;

   /**
      * @name     FORMAT_PARAMETERS
      * @desc     Formats parameter list for logging purposes.
      *           Converts SYS.ODCIVARCHAR2LIST to formatted string with proper NULL handling.
      * @example  select ENV_MANAGER.FORMAT_PARAMETERS(SYS.ODCIVARCHAR2LIST('param1=value1', 'param2=NULL')) from dual;
      * @ex_rslt  param1=value1 ,
      *           param2=NULL
   **/
   FUNCTION FORMAT_PARAMETERS(
      pParameterList SYS.ODCIVARCHAR2LIST
   ) RETURN VARCHAR2;


END ENV_MANAGER;

/

CREATE OR REPLACE EDITIONABLE PACKAGE BODY "CT_MRDS"."ENV_MANAGER"
AS
 
   ----------------------------------------------------------------------------------------------------
 
   PROCEDURE INIT_ERRORS IS
   BEGIN
      Errors(CODE_EMPTY_FILEURI_AND_RECKEY)        := Error_Record(CODE_EMPTY_FILEURI_AND_RECKEY,           MSG_EMPTY_FILEURI_AND_RECKEY);         --  -20001
      Errors(CODE_NO_CONFIG_MATCH_FOR_FILEURI)     := Error_Record(CODE_NO_CONFIG_MATCH_FOR_FILEURI,        MSG_NO_CONFIG_MATCH_FOR_FILEURI);      --  -20002
      Errors(CODE_MULTIPLE_MATCH_FOR_SRCFILE)      := Error_Record(CODE_MULTIPLE_MATCH_FOR_SRCFILE,         MSG_MULTIPLE_MATCH_FOR_SRCFILE);       --  -20003
      Errors(CODE_MISSING_COLUMN_DATE_FORMAT)      := Error_Record(CODE_MISSING_COLUMN_DATE_FORMAT,         MSG_MISSING_COLUMN_DATE_FORMAT);       --  -20004
      Errors(CODE_MULTIPLE_COLUMN_DATE_FORMAT)     := Error_Record(CODE_MULTIPLE_COLUMN_DATE_FORMAT,        MSG_MULTIPLE_COLUMN_DATE_FORMAT);      --  -20005
      Errors(CODE_DIDNT_GET_LOAD_OPERATION_ID)     := Error_Record(CODE_DIDNT_GET_LOAD_OPERATION_ID,        MSG_DIDNT_GET_LOAD_OPERATION_ID);      --  -20006
      Errors(CODE_NO_CONFIG_FOR_RECEIVED_FILE)     := Error_Record(CODE_NO_CONFIG_FOR_RECEIVED_FILE,        MSG_NO_CONFIG_FOR_RECEIVED_FILE);      --  -20007
      Errors(CODE_MULTI_CONFIG_FOR_RECEIVED_FILE)  := Error_Record(CODE_MULTI_CONFIG_FOR_RECEIVED_FILE,     MSG_MULTI_CONFIG_FOR_RECEIVED_FILE);   --  -20008
      Errors(CODE_FILE_NOT_FOUND_ON_CLOUD)         := Error_Record(CODE_FILE_NOT_FOUND_ON_CLOUD,            MSG_FILE_NOT_FOUND_ON_CLOUD);          --  -20009
      Errors(CODE_FILE_VALIDATION_FAILED)          := Error_Record(CODE_FILE_VALIDATION_FAILED,             MSG_FILE_VALIDATION_FAILED);           --  -20010
      Errors(CODE_NO_CONFIG_MATCH)                 := Error_Record(CODE_NO_CONFIG_MATCH,                    MSG_NO_CONFIG_MATCH);                  --  -20011
      Errors(CODE_UNKNOWN_PREFIX)                  := Error_Record(CODE_UNKNOWN_PREFIX,                     MSG_UNKNOWN_PREFIX);                   --  -20012
      Errors(CODE_TABLE_NOT_EXISTS)                := Error_Record(CODE_TABLE_NOT_EXISTS,                   MSG_TABLE_NOT_EXISTS);                 --  -20013
      Errors(CODE_COLUMN_NOT_EXISTS)               := Error_Record(CODE_COLUMN_NOT_EXISTS,                  MSG_COLUMN_NOT_EXISTS);                --  -20014
      Errors(CODE_UNSUPPORTED_DATA_TYPE)           := Error_Record(CODE_UNSUPPORTED_DATA_TYPE,              MSG_UNSUPPORTED_DATA_TYPE);            --  -20015
      Errors(CODE_MISSING_SOURCE_KEY)              := Error_Record(CODE_MISSING_SOURCE_KEY,                 MSG_MISSING_SOURCE_KEY);               --  -20016
      Errors(CODE_NULL_SOURCE_FILE_CONFIG_KEY)     := Error_Record(CODE_NULL_SOURCE_FILE_CONFIG_KEY,        MSG_NULL_SOURCE_FILE_CONFIG_KEY);      --  -20017
      Errors(CODE_DUPLICATED_SOURCE_KEY)           := Error_Record(CODE_DUPLICATED_SOURCE_KEY,              MSG_DUPLICATED_SOURCE_KEY);            --  -20018
      Errors(CODE_MISSING_CONTAINER_CONFIG)        := Error_Record(CODE_MISSING_CONTAINER_CONFIG,           MSG_MISSING_CONTAINER_CONFIG);         --  -20019
      Errors(CODE_MULTIPLE_CONTAINER_ENTRIES)      := Error_Record(CODE_MULTIPLE_CONTAINER_ENTRIES,         MSG_MULTIPLE_CONTAINER_ENTRIES);       --  -20020
      Errors(CODE_WRONG_DESTINATION_PARAM)         := Error_Record(CODE_WRONG_DESTINATION_PARAM,            MSG_WRONG_DESTINATION_PARAM);          --  -20021
      Errors(CODE_FILE_NOT_EXISTS_ON_CLOUD)        := Error_Record(CODE_FILE_NOT_EXISTS_ON_CLOUD,           MSG_FILE_NOT_EXISTS_ON_CLOUD);         --  -20022
      Errors(CODE_FILE_ALREADY_REGISTERED)         := Error_Record(CODE_FILE_ALREADY_REGISTERED,            MSG_FILE_ALREADY_REGISTERED);          --  -20023
      Errors(CODE_WRONG_DATE_TIMESTAMP_FORMAT)     := Error_Record(CODE_WRONG_DATE_TIMESTAMP_FORMAT,        MSG_WRONG_DATE_TIMESTAMP_FORMAT);      --  -20024
      Errors(CODE_ENVIRONMENT_NOT_SET)             := Error_Record(CODE_ENVIRONMENT_NOT_SET,                MSG_ENVIRONMENT_NOT_SET);              --  -20025
      Errors(CODE_CONFIG_VARIABLE_NOT_SET)         := Error_Record(CODE_CONFIG_VARIABLE_NOT_SET,            MSG_CONFIG_VARIABLE_NOT_SET);          --  -20026
      Errors(CODE_NOT_INPUT_SOURCE_FILE_TYPE)      := Error_Record(CODE_NOT_INPUT_SOURCE_FILE_TYPE,         MSG_NOT_INPUT_SOURCE_FILE_TYPE);       --  -20027
      Errors(CODE_EXP_DATA_FOR_HIST_FAILED)        := Error_Record(CODE_EXP_DATA_FOR_HIST_FAILED,           MSG_EXP_DATA_FOR_HIST_FAILED);         --  -20028
      Errors(CODE_RESTORE_FILE_FROM_TRASH)         := Error_Record(CODE_RESTORE_FILE_FROM_TRASH,            MSG_RESTORE_FILE_FROM_TRASH);          --  -20029
      Errors(CODE_CHANGE_STAT_TO_HISTORISED_FAILED):= Error_Record(CODE_CHANGE_STAT_TO_HISTORISED_FAILED,   MSG_CHANGE_STAT_TO_HISTORISED_FAILED); --  -20030
      Errors(CODE_MOVE_FILE_TO_TRASH_FAILED)       := Error_Record(CODE_MOVE_FILE_TO_TRASH_FAILED,          MSG_MOVE_FILE_TO_TRASH_FAILED);        --  -20031
      Errors(CODE_DROP_EXPORTED_FILES_FAILED)      := Error_Record(CODE_DROP_EXPORTED_FILES_FAILED,         MSG_DROP_EXPORTED_FILES_FAILED);       --  -20032

      Errors(CODE_UNKNOWN)                         := Error_Record(CODE_UNKNOWN,                         MSG_UNKNOWN);                          --  -20999

   END INIT_ERRORS;

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

   FUNCTION GET_DEFAULT_ENV
   RETURN VARCHAR2
   IS
      vDefaultEnv CT_MRDS.a_file_manager_config.config_variable_value%TYPE;
   BEGIN
      select config_variable_value
        into vDefaultEnv
        from CT_MRDS.a_file_manager_config
       where lower(environment_id)='default'
         and lower(config_variable)='environmentid';
      RETURN vDefaultEnv;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         RETURN NULL;
   END;

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

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

   PROCEDURE INIT_VARIABLES(
      pEnv VARCHAR2
   ) IS
   BEGIN
      for rec in (
         select
             ENVIRONMENT_ID
            ,REGION
            ,NAMESPACE
            ,INBOXBUCKETNAME
            ,DATABUCKETNAME
            ,HISTORYBUCKETNAME
            ,CREDENTIALNAME
            ,LOGGINGENABLED
            ,MINLOGLEVEL
            ,DEFAULTDATEFORMAT
            ,CONSOLELOGGINGENABLED
         from (
            select environment_id, config_variable, config_variable_value from CT_MRDS.A_FILE_MANAGER_CONFIG
            where environment_id=pEnv
            )
         pivot (
            min(config_variable_value)
            for config_variable in (
                'Region'                as Region
               ,'NameSpace'             as NameSpace
               ,'InboxBucketName'       as InboxBucketName
               ,'DataBucketName'        as DataBucketName
               ,'HistoryBucketName'     as HistoryBucketName
               ,'CredentialName'        as CredentialName
               ,'LoggingEnabled'        as LoggingEnabled
               ,'MinLogLevel'           as MinLogLevel
               ,'DefaultDateFormat'     as DefaultDateFormat
               ,'ConsoleLoggingEnabled' as ConsoleLoggingEnabled)
            )
         ) loop
            if   (rec.NAMESPACE            is NULL
               or rec.REGION               is NULL
               or rec.NAMESPACE            is NULL
               or rec.INBOXBUCKETNAME      is NULL
               or rec.DATABUCKETNAME       is NULL
               or rec.HISTORYBUCKETNAME    is NULL
               or rec.CREDENTIALNAME       is NULL
            ) THEN
               MSG_CONFIG_VARIABLE_NOT_SET := MSG_CONFIG_VARIABLE_NOT_SET
                     ||cgBL||'           '||'Details about existing Configuration Variables where environment_id='||pEnv||': '
                     ||cgBL||'           '||'-------------------------'
                     ||cgBL||'           '||'Region =            '||rec.Region
                     ||cgBL||'           '||'NameSpace =         '||rec.NameSpace
                     ||cgBL||'           '||'InboxBucketName =   '||rec.InboxBucketName
                     ||cgBL||'           '||'DataBucketName =    '||rec.DataBucketName
                     ||cgBL||'           '||'HistoryBucketName = '||rec.HistoryBucketName
                     ||cgBL||'           '||'CredentialName =    '||rec.CredentialName
                     ;
               LOG_PROCESS_EVENT(MSG_CONFIG_VARIABLE_NOT_SET, 'ERROR');
               RAISE_APPLICATION_ERROR(CODE_CONFIG_VARIABLE_NOT_SET, MSG_CONFIG_VARIABLE_NOT_SET);

            elsif (rec.LOGGINGENABLED      is NULL
               or rec.MINLOGLEVEL          is NULL
               or rec.DEFAULTDATEFORMAT    is NULL
            ) THEN
               vgMsgTmp := 'Missing configuration variables'
                     ||cgBL||'           '||'Details about existing Configuration Variables where environment_id='||pEnv||': '
                     ||cgBL||'           '||'-------------------------'
                     ||cgBL||'           '||'LoggingEnabled =    '||rec.LoggingEnabled
                     ||cgBL||'           '||'MinLogLevel =       '||rec.MinLogLevel
                     ||cgBL||'           '||'DefaultDateFormat = '||rec.DefaultDateFormat
                     ;
               LOG_PROCESS_EVENT(vgMsgTmp, 'WARNING');

            else
               gvNameSpace          := rec.NAMESPACE;
               gvRegion             := rec.REGION;
               gvInboxBucketName    := rec.INBOXBUCKETNAME;
               gvDataBucketName     := rec.DATABUCKETNAME;
               gvHistoryBucketName  := rec.HISTORYBUCKETNAME;
               gvCredentialName     := rec.CREDENTIALNAME;
               gvInboxBucketUri     := 'https://objectstorage.'||rec.REGION||'.oraclecloud.com/n/'||rec.NAMESPACE||'/b/'||rec.INBOXBUCKETNAME||'/o/';  
               gvDataBucketUri      := 'https://objectstorage.'||rec.REGION||'.oraclecloud.com/n/'||rec.NAMESPACE||'/b/'||rec.DATABUCKETNAME||'/o/';  
               gvHistoryBucketUri   := 'https://objectstorage.'||rec.REGION||'.oraclecloud.com/n/'||rec.NAMESPACE||'/b/'||rec.HISTORYBUCKETNAME||'/o/';  
               gvLoggingEnabled     := rec.LOGGINGENABLED;
               gvMinLogLevel        := rec.MINLOGLEVEL;
               gvDefaultDateFormat  := rec.DEFAULTDATEFORMAT;
               gvConsoleLoggingEnabled := NVL(rec.CONSOLELOGGINGENABLED, 'ON');
            end if;
      end loop;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            MSG_CONFIG_VARIABLE_NOT_SET := MSG_CONFIG_VARIABLE_NOT_SET_C
                  ||cgBL||'           '||'No configuration found for environment_id='||pEnv||' in A_FILE_MANAGER_CONFIG table';
            LOG_PROCESS_EVENT(MSG_CONFIG_VARIABLE_NOT_SET, 'ERROR', 'pEnv='||pEnv);
            RAISE_APPLICATION_ERROR(CODE_CONFIG_VARIABLE_NOT_SET, MSG_CONFIG_VARIABLE_NOT_SET);
         WHEN OTHERS THEN
            vgMsgTmp := 'Unexpected error while initializing variables for environment: '||pEnv
                  ||cgBL||'           '||'SQLERRM: '||SQLERRM;
            LOG_PROCESS_EVENT(vgMsgTmp, 'ERROR', 'pEnv='||pEnv);
            RAISE;
   END INIT_VARIABLES;

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

   FUNCTION GET_ERROR_MESSAGE(
      pCode PLS_INTEGER
   ) RETURN VARCHAR2
   IS
   BEGIN
      RETURN Errors(pCode).message;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         LOG_PROCESS_EVENT('No error message found for pCode='||pCode , 'WARNING', 'pCode='||pCode);
         LOG_PROCESS_EVENT('Update ENV_MANAGER package header with new code.' , 'WARNING', 'pCode='||pCode);
         RETURN NULL;
      WHEN OTHERS THEN
         LOG_PROCESS_EVENT(MSG_UNKNOWN , 'ERROR', 'pCode='||pCode);
         RAISE ERR_UNKNOWN;
   END GET_ERROR_MESSAGE;

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

   FUNCTION GET_ERROR_STACK(
      pFormat  VARCHAR2
     ,pCode    PLS_INTEGER
     ,pSourceFileReceivedKey CT_MRDS.A_SOURCE_FILE_RECEIVED.A_SOURCE_FILE_RECEIVED_KEY%TYPE DEFAULT NULL
   ) RETURN VARCHAR2
   IS
      vFullErrorCore VARCHAR2(32000);
      vFullErrorMsg  VARCHAR2(32000);
   BEGIN
--      vgErrorMessage    := SQLERRM|| cgBL;
--      vgErrorStack      := DBMS_UTILITY.FORMAT_ERROR_STACK;
--      vgErrorBacktrace  := DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
      vFullErrorCore :='Error Message:'
                     ||cgBL|| SQLERRM|| cgBL
                     ||'-------------------------------------------------------'
                     ||cgBL||'Error Stack:'
                     ||cgBL|| DBMS_UTILITY.FORMAT_ERROR_STACK
                     ||'-------------------------------------------------------'
                     ||cgBL||'Error Backtrace:'
                     ||cgBL|| DBMS_UTILITY.FORMAT_ERROR_BACKTRACE;
--      vFullErrorCore := REGEXP_REPLACE (vFullErrorCore,   pCode||': ', pCode||': '||GET_ERROR_MESSAGE(pCode) ,  1, 1);
      IF (pFormat = 'TABLE') THEN
         vFullErrorMsg := vFullErrorCore;
      ELSE
         vFullErrorMsg := cgBL||'------------------------------------------------------+'
                        ||cgBL||vFullErrorCore
                              ||'------------------------------------------------------+';
      END IF;
--      IF pSourceFileReceivedKey is not null THEN
--         vFullErrorMsg := vFullErrorMsg ||cgBL||GET_DET_SOURCE_FILE_RECEIVED_INFO(pSourceFileReceivedKey,1,1,1);
--      END IF;

      RETURN vFullErrorMsg;
   EXCEPTION
      WHEN OTHERS THEN
         LOG_PROCESS_EVENT(MSG_UNKNOWN , 'ERROR', 'pFormat='||pFormat);
         RETURN NULL;
   END GET_ERROR_STACK;

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

   FUNCTION FORMAT_PARAMETERS(
      pParameterList SYS.ODCIVARCHAR2LIST
   ) RETURN VARCHAR2 IS
      vResult VARCHAR2(10000);
   BEGIN
      FOR i IN 1 .. pParameterList.COUNT LOOP
--         dbms_output.put_line('pParameterList(i): '||pParameterList(i));
         if i < pParameterList.COUNT then vResult := vResult || replace(pParameterList(i), '''NULL''', 'NULL') ||' ,'|| cgBL;
                                     else vResult := vResult || replace(pParameterList(i), '''NULL''', 'NULL');
         end if;
      END LOOP;
      RETURN vResult;
   EXCEPTION
      WHEN OTHERS THEN
         LOG_PROCESS_EVENT('Error while formating parameters.' , 'WARNING');
         RETURN NULL;
   END FORMAT_PARAMETERS;

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



   PROCEDURE LOG_PROCESS_EVENT (
       pLogMessage   VARCHAR2
      ,pLogLevel     VARCHAR2 DEFAULT 'ERROR'
      ,pParameters   VARCHAR2 DEFAULT NULL
      ,pProcessName  VARCHAR2 DEFAULT 'FILE_MANAGER'
   ) IS
   PRAGMA AUTONOMOUS_TRANSACTION;

      vLoggingEnabled   VARCHAR2(10);
      vMinLogLevel      VARCHAR2(10);
      vCallStack        VARCHAR2(10000);
      vProcedureName    VARCHAR2(100);
      vProcedureLevel   PLS_INTEGER;
      vTotalLines       PLS_INTEGER;
      vCurrentLine      PLS_INTEGER;

      -- Map of priority level
      TYPE logLevelMap IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
      vLogLevels logLevelMap;

   BEGIN
      -- Prority logging level (higher -> more important)
      vLogLevels('DEBUG')   := 1;
      vLogLevels('INFO')    := 2;
      vLogLevels('WARNING') := 3;
      vLogLevels('ERROR')   := 4;

      -- Check id logging is TURN-OFF
      IF gvLoggingEnabled = 'OFF' THEN
         RETURN;
      END IF;
      -- Check logging level
      IF vLogLevels(pLogLevel) < vLogLevels(gvMinLogLevel) THEN
         RETURN;
      END IF;

      vCallStack := DBMS_UTILITY.FORMAT_CALL_STACK;
      vProcedureName := REGEXP_SUBSTR(vCallStack, 'package body\s+\w+\.(\w+\.\w+)', 1, 2, NULL, 1);
      vTotalLines := REGEXP_COUNT(vCallStack, CHR(10)) + 1;
      vCurrentLine := REGEXP_COUNT(SUBSTR(vCallStack, 1, INSTR(vCallStack, vProcedureName) - 1), CHR(10)) + 1;
      vProcedureLevel := (vTotalLines - vCurrentLine + 1) - 3;
      vProcedureName := LPAD(vProcedureName, LENGTH(vProcedureName) + 2*vProcedureLevel, ' ');

      INSERT INTO CT_MRDS.A_PROCESS_LOG (guid, username, osuser, machine, module, process_name, procedure_name, procedure_parameters, log_level, log_message)
      VALUES (guid, gvUsername, gvOsuser, gvMachine, gvModule, pProcessName, vProcedureName, pParameters, pLogLevel, pLogMessage);

      COMMIT;

      -- Also output to console for immediate visibility (if enabled)
      IF gvConsoleLoggingEnabled = 'ON' THEN
         DBMS_OUTPUT.PUT_LINE('[' || TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') || '] [' || pLogLevel || '] ' || vProcedureName || ': ' || pLogMessage);
      END IF;

   END LOG_PROCESS_EVENT;

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

BEGIN
   INIT_ERRORS;
   guid        := sys_guid();
   gvUsername  := SYS_CONTEXT('USERENV', 'SESSION_USER');
   gvOsuser    := SYS_CONTEXT('USERENV', 'OS_USER');
   gvMachine   := SYS_CONTEXT('USERENV', 'HOST');
   gvModule    := SYS_CONTEXT('USERENV', 'MODULE');

   -- Get info about EnvironmentID. Without it package cannot proceed further.
   -- Information about environment is needed to get proper configuration values
   -- It can be set up in two different ways :
   -- 1. Set it on session level:       execute DBMS_SESSION.SET_IDENTIFIER (client_id => 'dev');
   -- 2. Set it on configuration level: Insert into CT_MRDS.A_FILE_MANAGER_CONFIG (ENVIRONMENT_ID,CONFIG_VARIABLE,CONFIG_VARIABLE_VALUE) values ('default','environment_id','dev');
   -- Session level setup (1.) takes precedence over configuration level one (2.)

   gvEnv := nvl(SYS_CONTEXT ('USERENV', 'CLIENT_IDENTIFIER'), GET_DEFAULT_ENV());
   if gvEnv is null then
      dbms_output.put_line(MSG_ENVIRONMENT_NOT_SET);
      LOG_PROCESS_EVENT(MSG_ENVIRONMENT_NOT_SET, 'ERROR');
      RAISE_APPLICATION_ERROR(CODE_ENVIRONMENT_NOT_SET, MSG_ENVIRONMENT_NOT_SET);
   else
      dbms_output.put_line('EnvironmentID set to: '||gvEnv);
   end if;

   INIT_VARIABLES(pEnv => gvEnv);
END ENV_MANAGER;

/
