

#ifndef FEE_PRV_FSIF_H
#define FEE_PRV_FSIF_H

/* Disable the Fee common part when the Fs1 is selected - currently the Fs1 is a complete Fee */
# if(defined(FEE_PRV_CFG_SELECTED_FS) && (1 != FEE_PRV_CFG_SELECTED_FS))

/*
 * The FsIf (Filesystem-Interace) unit is the connection from the main function to the actual file system.
 * Currently only one filesystem (Fs2) is supported.
 * Due to that the FsIf unit is currently only a direct mapper to Fs2.
*/

/*
 **********************************************************************************************************************
 * Includes
 **********************************************************************************************************************
*/
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
#include "rba_FeeFs2.h"
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
#include "rba_FeeFs3_Prv_Blk.h"
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
#include "rba_FeeFs1x.h"
#  endif

/*
 **********************************************************************************************************************
 * Extern Declarations
 **********************************************************************************************************************
*/
LOCAL_INLINE Std_ReturnType Fee_Prv_FsIfInit(void)                                                                     ;

LOCAL_INLINE void Fee_Prv_FsIfSetMode(MemIf_ModeType mode_en)                                                          ;

LOCAL_INLINE void Fee_Prv_FsIfRead                (Fee_Prv_OrderJob_tst const * order_pcst)                            ;
LOCAL_INLINE void Fee_Prv_FsIfWrite               (Fee_Prv_OrderJob_tst const * order_pcst)                            ;
LOCAL_INLINE void Fee_Prv_FsIfInvalidateBlock     (Fee_Prv_OrderJob_tst const * order_pcst)                            ;
LOCAL_INLINE void Fee_Prv_FsIfRbMaintainBlock     (Fee_Prv_OrderJob_tst const * order_pcst)                            ;
LOCAL_INLINE void Fee_Prv_FsIfEraseImmediateBlock (Fee_Prv_OrderJob_tst const * order_pcst)                            ;

LOCAL_INLINE void Fee_Prv_FsIfCancel              (void)                                                               ;
LOCAL_INLINE void Fee_Prv_FsIfRbTriggerReorg      (void)                                                               ;

LOCAL_INLINE void Fee_Prv_FsIfRbGetNrFreeBytesAndFatEntries (uint32 * nrFreeBytes_pu32, uint32 * nrFreeFatEntries_pu32, boolean isEraseAccepted_b);

LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfWriteDo                (void)                                             ;
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfReadDo                 (void)                                             ;
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfInvalidateBlockDo      (void)                                             ;
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfRbMaintainBlockDo      (void)                                             ;
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfEraseImmediateBlockDo  (void)                                             ;
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfBackground             (void)                                             ;
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfRbTriggerReorgDo       (void)                                             ;

LOCAL_INLINE uint32 Fee_Prv_FsIfRbGetSectorChgCntr                  (void)                                             ;
LOCAL_INLINE uint32 Fee_Prv_FsIfRbGetFreeSpace                      (void)                                             ;

LOCAL_INLINE boolean Fee_Prv_FsIfRbIsSoftReorgOngoing               (void)                                             ;
LOCAL_INLINE boolean Fee_Prv_FsIfRbIsHardReorgOngoing               (void)                                             ;
LOCAL_INLINE boolean Fee_Prv_FsIfRbIsSectorEraseOngoing             (void)                                             ;
/*
 **********************************************************************************************************************
 * Inlines
 **********************************************************************************************************************
*/

/**
 * \brief   Initialize a file system.
*/
LOCAL_INLINE Std_ReturnType Fee_Prv_FsIfInit(void)
{
    Std_ReturnType stRetVal_en;
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    stRetVal_en = rba_FeeFs2_Init();
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    stRetVal_en = rba_FeeFs3_Prv_BlkIni();
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    stRetVal_en = rba_FeeFs1x_Init();
#  else
    stRetVal_en = E_NOT_OK;
#  endif

    return(stRetVal_en);
}

/**
 * \brief   Set the execution mode.
 *
 * \param   mode_en:  fast or slow mode
*/
LOCAL_INLINE void Fee_Prv_FsIfSetMode(MemIf_ModeType mode_en)
{
    /* In Fs1x and Fs3, the execution mode is retrieved via Fee_Prv_GetDriverMode.
     * In Fs2, the feature is not (yet) supported. */
    (void)mode_en;

    return;
}

/**
 * \brief   Let the file system start a read job.
 *
 * \param   order_pcst  Order which contains all information about the read job.
*/
LOCAL_INLINE void Fee_Prv_FsIfRead(Fee_Prv_OrderJob_tst const * order_pcst)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_Read(order_pcst);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs3_Prv_BlkRead(order_pcst);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs1x_Read(order_pcst);
#  endif

    return;
}

/**
 * \brief   Let the file system start a write job.
 *
 * \param   order_pcst  Order which contains all information about the write job.
*/
LOCAL_INLINE void Fee_Prv_FsIfWrite(Fee_Prv_OrderJob_tst const * order_pcst)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_Write(order_pcst);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs3_Prv_BlkWrite(order_pcst);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs1x_Write(order_pcst);
#  endif

    return;
}

/**
 * \brief   Let the file system start an invalidate job.
 *
 * \param   order_pcst  Order which contains all information about the invalidate job.
*/
LOCAL_INLINE void Fee_Prv_FsIfInvalidateBlock(Fee_Prv_OrderJob_tst const * order_pcst)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_InvalidateBlock(order_pcst);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs3_Prv_BlkInvalidate(order_pcst);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs1x_Invalidate(order_pcst);
#  endif

    return;
}

/**
 * \brief Let the file system start a maintain job.
 *
 * \param   order_pcst  Order which contains all information about the maintain job.
*/
LOCAL_INLINE void Fee_Prv_FsIfRbMaintainBlock(Fee_Prv_OrderJob_tst const * order_pcst)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_BlockMaintenance(order_pcst);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs3_Prv_BlkMaintain(order_pcst);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs1x_Rb_Maintain(order_pcst);
#  endif

    return;
}

/**
 * \brief   Let the file system start an erase immediate job.
 *
 * \param   order_pcst  Order which contains all information about the erase immediate job.
 *
 * \attention   Currently no file system supports erase immediate.
*/
LOCAL_INLINE void Fee_Prv_FsIfEraseImmediateBlock(Fee_Prv_OrderJob_tst const * order_pcst)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_EraseImmediateBlock(order_pcst);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs3_Prv_BlkErase(order_pcst);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    // not a valid Fs1x job
    (void) *order_pcst;
#  endif

    return;
}

/**
 * \brief   Let the file system cancel a job.
 *          Can also be called when a background maintenance action shall be called.
 *          This is for example used to abort a running soft reorganization.
 *
*/
LOCAL_INLINE void Fee_Prv_FsIfCancel(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_Cancel();
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs3_Prv_BlkCancel();
#  endif

    return;
}

/**
 * \brief   Let the file system start a triggered reorg job.
 *
 * \param   order_pcst  Order which contains all information about the triggered reorg job.
*/
LOCAL_INLINE void Fee_Prv_FsIfRbTriggerReorg(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    /* Feature currently not supported */
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    /* Feature currently not supported */
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs1x_TriggerReorg();
#  endif

    return;
}

/**
 * \brief   Do the work of a write job.
 *
 * \retval  MEMIF_JOB_PENDING   Write is not yet finished
 * \retval  MEMIF_JOB_OK        Write finished successfully
 * \retval  MEMIF_JOB_FAILED    Write failed
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfWriteDo(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_WriteDo());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkWriteDo());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_BlockJobDo());
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Do the work of a read job.
 *
 * \retval  MEMIF_JOB_PENDING           Read is not yet finished
 * \retval  MEMIF_JOB_OK                Read finished successfully
 * \retval  MEMIF_BLOCK_INCONSISTENT    Block was not found or the data was not consistent
 * \retval  MEMIF_BLOCK_INVALID         Block was previously invalidated with an invalidate order
 * \retval  MEMIF_JOB_FAILED            Read failed
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfReadDo(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_ReadDo());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkReadDo());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_BlockJobDo());
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Do the work of an invalidate job.
 *
 * \retval  MEMIF_JOB_PENDING   Invalidate is not yet finished
 * \retval  MEMIF_JOB_OK        Invalidate finished successfully
 * \retval  MEMIF_JOB_FAILED    Invalidate failed
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfInvalidateBlockDo(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_InvalidateBlockDo());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkInvalidateDo());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_BlockJobDo());
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Do the work of an Maintain job.
 *
 * \retval  MEMIF_JOB_PENDING   Maintain is not yet finished
 * \retval  MEMIF_JOB_OK        Maintain finished successfully
 * \retval  MEMIF_JOB_FAILED    Maintain failed
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfRbMaintainBlockDo(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_BlockMaintenanceDo());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkMaintainDo());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_BlockJobDo());
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Do the work of an erase immediate job.
 *
 * \retval  MEMIF_JOB_PENDING   Erase immediate is not yet finished
 * \retval  MEMIF_JOB_OK        Erase immediate finished successfully
 * \retval  MEMIF_JOB_FAILED    Erase immediate failed
 *
 * \attention   Currently no file system supports erase immediate.
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfEraseImmediateBlockDo(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_EraseImmediateBlockDo());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkEraseDo());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(MEMIF_JOB_FAILED);
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Let the file system perform some background actions.
 *          This can for example mean erasing a sector in the background.
 *
 * \retval  MEMIF_JOB_PENDING   A background operation is currently running
 * \retval  MEMIF_JOB_OK        No background operation is currently running
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfBackground(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_Background());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkBackground());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_Background());
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Do the work of a triggered reorg job.
 *
 * \retval  MEMIF_JOB_PENDING   Triggered reorg is not yet finished
 * \retval  MEMIF_JOB_OK        Triggered reorg is finished successfully
 * \retval  MEMIF_JOB_FAILED    Triggered reorg failed
*/
LOCAL_INLINE MemIf_JobResultType Fee_Prv_FsIfRbTriggerReorgDo(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(MEMIF_JOB_FAILED);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(MEMIF_JOB_FAILED);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_TriggerReorgDo());
#  else
    return(MEMIF_JOB_FAILED);
#  endif
}

/**
 * \brief   Function to return sector change counter
 *
 * \retval  sector change counter
*/
LOCAL_INLINE uint32 Fee_Prv_FsIfRbGetSectorChgCntr(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_GetSectorChgCntr());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    /* not supported */
    return(0u);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_GetSectorChgCntr());
#  else
    return(0u);
#  endif
}

/**
 * \brief   Get the amount of free space in DFLASH
 *
 * \return  Amount of free space in bytes
*/
LOCAL_INLINE uint32 Fee_Prv_FsIfRbGetFreeSpace(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(0u);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkGetFreeSpace());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_GetFreeSpace());
#  else
    return(0u);
#  endif
}

/**
 * \brief   Get the amount of free user data space and number of free control data space (FAT entries) in DFLASH before a hard reorganization will be started.
 *          If erase operations are not accepted by the user, free non erased sectors will not be considered for user data space evaluation.
 *
 * \param   nrFreeBytes_pu32       The pointer to the address, where the number of free data bytes information shall be written.
 * \param   nrFreeFatEntries_pu32  The pointer to the address, where the number of free FAT entries information shall be written.
 * \param   isEraseAccepted_b      Information how to handle free non erased sectors.
 *                                 TRUE:  Free non erased sectors shall be considered, erase operations may occur when writing the given number of bytes
 *                                 FALSE: Free non erased sectors shall not be considered, no erase operations when writing the given number of bytes
 */
LOCAL_INLINE void Fee_Prv_FsIfRbGetNrFreeBytesAndFatEntries(uint32 * nrFreeBytes_pu32, uint32 * nrFreeFatEntries_pu32, boolean isEraseAccepted_b)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    rba_FeeFs2_GetNrFreeBytesAndFatEntries(nrFreeBytes_pu32, nrFreeFatEntries_pu32, isEraseAccepted_b);
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    *nrFreeBytes_pu32      = 0u;
    *nrFreeFatEntries_pu32 = 0u;
    (void)isEraseAccepted_b;
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    *nrFreeBytes_pu32      = 0u;
    *nrFreeFatEntries_pu32 = 0u;
    (void)isEraseAccepted_b;
#  else
    *nrFreeBytes_pu32      = 0u;
    *nrFreeFatEntries_pu32 = 0u;
    (void)isEraseAccepted_b;
#  endif
}

/**
 * \brief   Get the status of soft reorg (only when in driverstate background!)
 *
 * \return  Status of soft reorg
*/
LOCAL_INLINE boolean Fee_Prv_FsIfRbIsSoftReorgOngoing(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_IsReorgOngoing());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkIsSoftDefragOngoing());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_IsSoftReorgOngoing());
#  else
    return(FALSE);
#  endif
}

/**
 * \brief   Get the status of hard reorg
 *
 * \return  Status of hard reorg
*/
LOCAL_INLINE boolean Fee_Prv_FsIfRbIsHardReorgOngoing(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_IsReorgOngoing());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs3_Prv_BlkIsHardDefragOngoing());
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_IsHardReorgOngoing());
#  else
    return(FALSE);
#  endif
}

/**
 * \brief   Get the status of sector erase
 *
 * \return  Status of sector erase
*/
LOCAL_INLINE boolean Fee_Prv_FsIfRbIsSectorEraseOngoing(void)
{
#  if(2 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs2_IsSectorEraseOngoing());
#  elif(3 == FEE_PRV_CFG_SELECTED_FS)
    return(FALSE);
#  elif(10 == FEE_PRV_CFG_SELECTED_FS)
    return(rba_FeeFs1x_IsSectorEraseOngoing());
#  else
    return(FALSE);
#  endif
}

/* 1 != FEE_PRV_CFG_SELECTED_FS */
# endif

/* FEE_PRV_FSIF_H */
#endif
