////////////////////////////////////////////////////////////////////////////////
//                                                                             /
// 2012-2019 (c) Baical                                                        /
//                                                                             /
// This library is free software; you can redistribute it and/or               /
// modify it under the terms of the GNU Lesser General Public                  /
// License as published by the Free Software Foundation; either                /
// version 3.0 of the License, or (at your option) any later version.          /
//                                                                             /
// This library is distributed in the hope that it will be useful,             /
// but WITHOUT ANY WARRANTY; without even the implied warranty of              /
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           /
// Lesser General Public License for more details.                             /
//                                                                             /
// You should have received a copy of the GNU Lesser General Public            /
// License along with this library.                                            /
//                                                                             /
////////////////////////////////////////////////////////////////////////////////
#ifndef BK_API_TRACE_STORAGE_H
#define BK_API_TRACE_STORAGE_H

/// <summary> GUID of the reader </summary>
#define BK_READER_GUID_TRACE  { 0x3AC067E2, 0xCA3A, 0x4207, { 0xB5, 0xB2, 0x3C, 0xC1, 0xF7, 0x7A, 0x67, 0x4A } }

#include "PAPI.h"

namespace Bk
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Trace level </summary>
    enum eTraceLevel
    {
        /// <summary> Trace </summary>
        eTraceLevelTrace = 0,
        /// <summary> Debug </summary>
        eTraceLevelDebug ,
        /// <summary> Info </summary>
        eTraceLevelInfo ,
        /// <summary> Warning </summary>
        eTraceLevelWarning ,
        /// <summary> Error </summary>
        eTraceLevelError ,
        /// <summary> Critical </summary>
        eTraceLevelCritical ,

        /// <summary> Level max count </summary>
        eTraceLevelsCount           
    };
    PRAGMA_PACK_ENTER(2)

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Trace item description structure </summary>
    struct stTrace
    {
        /// <summary> Trace level </summary>
        Bk::eTraceLevel eLevel;
        /// <summary> Trace item unique Id </summary>
        tUINT16 wID;
        /// <summary> Sequence number </summary>
        tUINT32 dwSequence;
        /// <summary> Processor core number </summary>
        tUINT8 bProcessor; //processor number
        /// <summary> Module Id </summary>
        tUINT32 dwModuleID;
        /// <summary> Thread Id </summary>
        tUINT32 dwThreadID;
        /// <summary> 
        /// This time is offset from stream time: Bk::stStorageInfo::sStream_Time.
        /// To get absolute trace time (value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC)):
        /// Bk::stStorageInfo::sStream_Time + stTrace::qwTime.
        ///</summary>
        tUINT64 qwTime; 
        /// <summary> Source file line number </summary>
        tUINT16 wLine;
        /// <summary> File path </summary>
        tXCHAR *pFile_Path;
        /// <summary> File name </summary>
        tXCHAR *pFile_Name;
        /// <summary> Function name </summary>
        tXCHAR *pFunction;
        /// <summary> Trace text </summary>
        tXCHAR *pMessage;
        /// <summary> Trace text max size </summary>
        size_t szMessage;
        /// <summary> thread name </summary>
        tACHAR *pThreadName; 
        /// <summary> module name </summary>
        tACHAR *pModuleName; 
    } ATTR_PACK(2);
    PRAGMA_PACK_EXIT()

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Interface for filtering predicate </summary>
    class ITraceFilter
    {
    public:
        /// <summary> Checks does trace match the external filter predicate </summary>
        /// <param name="i_pItem"> trace item </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Check(const Bk::stTrace *i_pItem) = 0;

        /// <summary> Does predicate use text matching or not </summary>
        /// <returns>TRUE - it uses text matching, else FALSE</returns>  
        virtual tBOOL __stdcall Is_Text_Search() = 0;
                                                                                      
        /// <summary> Increases object reference counter </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Add_Ref() = 0;

        /// <summary> Decreases object reference counter. If 0 - object will be self-destroyed </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Release() = 0;
    };

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Trace reader interface </summary>
    class ITraceReader
    {
    public:
        /// <summary> Get amount of trace items for every trace level, Checks does trace match the external filter predicate </summary>
        /// <param name="o_pCounters"> counters array, will contains Bk::eTraceLevelsCount elements ! output value </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Get_Counters(tUINT64 **o_pCounters) = 0;

        /// <summary> Get total amount of trace items </summary>
        /// <param name="o_pCount"> traces count </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Get_Count(tUINT64 *o_pCount) = 0;

        /// <summary> Get trace item by index </summary>
        /// <param name="i_qwIndex"> trace item index, to obtain max index call Get_Count() function </param>
        /// <param name="o_pItem"> trace item </param>
        /// <param name="i_bFormat">
        /// text formatting flag, text formatting is expensive operation and in some cases it can be ignored to save CPU 
        /// </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>
        virtual Bk::eResult __stdcall Get_Trace(tUINT64 i_qwIndex, Bk::stTrace *o_pItem, tBOOL i_bFormat) = 0;

        /// <summary> Set filter and get filtered result </summary>
        /// <param name="i_pFilter"> filter interface </param>
        /// <param name="i_pPath"> path to new storage, If NULL - default path will be used </param>
        /// <param name="o_pReader"> result reader, output parameter </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Set_Filter(Bk::ITraceFilter *i_pFilter, const tXCHAR *i_pPath, Bk::ITraceReader **o_pReader) = 0;

        /// <summary> Get filter state </summary>
        /// <param name="o_pPercent"> state [0% .. 100%], output parameter </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Get_Filter_Status(tINT32 *o_pPercent)  = 0;

        /// <summary> Clear filter </summary>
        /// <param name="i_bDelete"> TRUE: delete filtered content, FALSE: keep filtered content on HDD </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Clr_Filter(tBOOL i_bDelete)  = 0;

        /// <summary> Increases object reference counter </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Add_Ref() = 0;

        /// <summary> Decreases object reference counter. If 0 - object will be self-destroyed </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Release() = 0;
    };                                                                    
}

#endif //BK_API_TRACE_STORAGE_H