////////////////////////////////////////////////////////////////////////////////
//                                                                             /
// 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_H
#define BK_API_H

/// <summary> shared P7 engine instance name </summary>
#define BK_SHARED_P7                        TM("BK:P7")

/// <summary> shared P7 trace channel name </summary>
#define BK_SHARED_TRACE                     TM("BK:Tr")

/// <summary> shared P7 telemetry channel name </summary>
#define BK_SHARED_TELEMETRY                 TM("BK:Tl")

/// <summary> maximum length of plugin name in characters </summary>
#define BK_PLUGIN_NAME_MAX_LENGTH           (256)

/// <summary> current version of API </summary>
#define BK_PLUGIN_API_VERSION               (0x00020000)

// {339120F2-C940-49b8-AC7A-86FDEEDBCCA8}
#define BK_GUID_STREAM_TRACE                {0x339120f2, 0xc940, 0x49b8, {0xac, 0x7a, 0x86, 0xfd, 0xee, 0xdb, 0xcc, 0xa8}}
 

// {C9F87FB7-1FF7-4a75-9539-1B0458B1B339}
#define BK_GUID_STREAM_TELEMETRY_V1         {0xc9f87fb7, 0x1ff7, 0x4a75, {0x95, 0x39, 0x1b, 0x04, 0x58, 0xb1, 0xb3, 0x39}}


// {0x7D2A5A5B, 0x6A11, 0x4D54, {0x87, 0x80, 0x27, 0x87, 0xF8, 0x28, 0x70, 0x71}
#define BK_GUID_STREAM_TELEMETRY_V2         {0x7D2A5A5B, 0x6A11, 0x4D54, {0x87, 0x80, 0x27, 0x87, 0xF8, 0x28, 0x70, 0x71}}



#if defined(_WIN32) || defined(_WIN64)
#elif !defined(BK_API_STRUCTURES)
    #define BK_API_STRUCTURES
    typedef struct _FILETIME 
    {
        tUINT32 dwLowDateTime;
        tUINT32 dwHighDateTime;
    } FILETIME;
#endif


namespace Bk
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Baical module types </summary>
    enum ePluginType
    {
        /// <summary> Provider module </summary>
        ePluginProvider = 0,
        /// <summary> Storage module </summary>
        ePluginStorage,
        /// <summary> Viewer module: GUI </summary>
        ePluginViewerGUI,
        /// <summary> Viewer module: CLI </summary>
        ePluginViewerCLI,
        /// <summary> Streams dispatcher module </summary>
        ePluginStreamsDispatcher,
        /// <summary> Streams processor module </summary>
        ePluginStreamsProcessor,
                                                                           
        ePluginsCount                                                            
    };

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Baical plugins result codes</summary>
    enum eResult
    {
        /// <summary> Success result code </summary>
        eOk = 0,

        /// <summary> general error code </summary>
        eError,
        /// <summary> arguments error </summary>
        eErrorWrongInput,
        /// <summary> no available memory </summary>
        eErrorNoBuffer,
        /// <summary> internal error </summary>
        eErrorInternal,
        /// <summary> function isn't supported </summary>
        eErrorNotSupported,
        /// <summary> function isn't implemented </summary>
        eErrorNotImplemented,
        /// <summary> access to function of file is blocked by the system </summary>
        eErrorBlocked,
        /// <summary> functionality is not active for the time being </summary>
        eErrorNotActive,
        /// <summary> not appropriate plugin for the stream </summary>
        eErrorMissmatch,
        /// <summary> stream is closed </summary>
        eErrorClosed,
        /// <summary> timeout </summary>
        eErrorTimeout,
        /// <summary> can't write to file </summary>
        eErrorFileWrite
    };


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Interfaces enumerator, used by IUnknown::Query_Interface </summary>
    enum eInterface
    {
        /// <summary> Provider import interface </summary>
        eInterfaceCore            = 0,
        eInterfaceReader             ,
        eInterfaceTraceReader        ,
        eInterfaceTelemetryReader    ,
        eInterfaceStoragesEnumerator ,
        eInterfaceStreams            ,
        eInterfaceStreamExTelemetry  ,
        eInterfaceStreamExTrace      ,

        eInterfacesCount
    };


    PRAGMA_PACK_ENTER(8)
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Plugin description structure </summary>
    struct stPluginInfo
    {
        /// <summary> global ID </summary>
        GUID         sGUID;
        /// <summary> plugin type </summary>
        ePluginType  eType;
        /// <summary> minimum supported API version, current is BK_PLUGIN_API_VERSION </summary>
        tUINT32      dwAPI_Version;
        /// <summary> plugin version </summary>
        tUINT64      qwVersion;
        /// <summary> plugin supported formats, for example: "My format (*.myformat);Another format(*.another)" </summary>
        const XCHAR  *pFormats;
        /// <summary> plugin name </summary>
        XCHAR        pName[BK_PLUGIN_NAME_MAX_LENGTH];
    }ATTR_PACK(8);

    PRAGMA_PACK_EXIT()


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> IUnknown interface, root interface for all others plugins interfaces  </summary>
    class IUnknown
    {
    public:
        /// <summary> Query interface </summary>
        /// <param name="i_eId">  interface ID </param>
        /// <param name="o_rUnknown"> resulting interface, use dynamic_cast to cast the interface to appropriate one </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Query_Interface(Bk::eInterface i_eId, void *&o_rUnknown) = 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_H