/*!
 * (C) 2004 "Kaspersky Lab"
 *
 * \file conn/connector.h
 * \author Андрей Казачков
 * \date 2004
 * \brief Интерфейс, отвечающий за интеграцию приложений с системой 
            администрирования. 
 *
 */
/*KLCSAK_PUBLIC_HEADER*/

#ifndef KLCONN_CONNECTOR_H
#define KLCONN_CONNECTOR_H

#include "./conn_types.h"
#include "./settings_synchronizer.h"
#include "./task_settings_synchronizer.h"
#include "./tasks_synchronizer.h"
#include "./app_synchronizer.h"
#include "./notifier.h"


namespace KLCONN
{
#ifdef _WIN32
    #define KLCONN_CALL __cdecl
#else
    #define KLCONN_CALL
#endif

/*!
    \brief Модуль, отвечающий за интеграцию приложений с системой
        администрирования.
	
    Данный модуль используется разработчиками приложений для интеграции
    приложений с системой администрирования.  Используется следующая
    модель интеграции:

    1) Приложение имеет набор настроек, которые группируются в разделы.
    2) Функциональность приложения представляется администратору в виде
        набора задач. Задачи имеют настройки и могут запускаться вручную,
        по расписанию либо при старте приложения.  Резидентные задачи
        должны поддерживать возможность работы с измененными настройками
        без перезапуска приложения.
    3) Приложение публикует набор событий.  Правила реакции на события
        определяются администратором.
    4) Приложение предоставляет набор статистических показателей своей
        работы.
    5) Администратор может определеть политику для настроек и задач
       приложений.  Данные в политике, запрещенные к изменению
       администратором, имеют приоритет над локальными настройками
       приложения.


    Все вызовы методов интерфейсов, реализуемых библиотекой интеграции,
    могут производится на разных нитях, но при этом сериализуются 
    вызывающей стороной. Т.е. одновременно не могут быть вызваны никакие 
    методы, реализованные в данной библиотеке интеграции.

        По вызовы библиотеки интеграции делаются на нитях из общего пула. 
    Однако, при необходимости, библиотека интеграции может быть
    зарегистрирована для работы в "однопоточном" режиме - в этом случае 
    перед загрузкой библиотеки интеграции будет создан "рабочий" поток,
    а контексте которого будут вызываться все методы, реализованные в 
    библиотеке интеграции; после выгрузки библиотеки  интеграции поток
    завершит свою работу. 

        Такой "однопоточный" режим может быть полезен, например, если
    библиотека интеграции использует COM -- в этом случае, в методе
    Connector::StartIntegration библиотека может вызвать  CoInitialize(),
    чтобы проинициализировать COM для "рабочего" потока, далее обращения к
    библиотеке интеграции делаются именно на этом потоке, при завершени
    работы в методе Connector::StopIntegration() библиотека может вызвать
    CoUninitialize().

    Подробнее о интеграции приложений с системой администрирования можно
    прочитать в документе CS AdminKit Product Integration.doc.    
    */

	/*!
		\brief Интерфейс DLL интеграции.
		DLL интеграции должна экспортировать функции KLCONN_INITDLL, 
        KLCONN_DEINITDLL и KLCONN_CREATECONNECTOR (см. ниже).        
        Система администрирования сериализует вызовы этих функций в
        контексте процесса, т.е. одновременно не более чем одна нить может
        находится внутри любой из этих функций. Количество вызовов
        KLCONN_INITDLL строго равно количеству вызовов KLCONN_DEINITDLL.
	*/

	/*!
		\brief Инициализация  DLL интеграции.
        

		__declspec(dllexport)
			bool KLCONN_INITDLL(KLERR::Error**  ppError)
		{			
			//Выполняем какие-либо действия
			//.............................
		};

	  \param	ppError [out] описание ошибки возникшей при инициализации
            билиотеки интеграции
      \return true - если инициализация прошла успешно, false - в случае
            ошибки.
      \exception  функция не выбрасывает исключений
	*/

	#define KLCONN_INITDLL  KLCONN_Init
	
	typedef bool (KLCONN_CALL * InitDll)(KLERR::Error** ppError);

	/*!
		\brief Деинициализация DLL интеграции.

        \exception функция не выбрасывает исключений

	    __declspec(dllexport)
		    void KLCONN_DEINITDLL()
		{			
			//Выполняем какие-либо действия
			//.............................
		};	
	*/

	#define KLCONN_DEINITDLL    KLCONN_Deinit

	typedef void (KLCONN_CALL * DeinitDll)();

	/*!
		\brief Получение указателя на интерфейс KLCONN::Connector для
            указанного приложения.

        \param szwProduct [in] - имя приложения
        \param szwVersion [in] - версия приложения
        \param ppConnector [out] - указатель на переменную, в которую
                                будет записан указатель на интерфейс
        \param ppError [out] - указатель на переменную, в которую
                                будет записано описание ошибки

        \exception функция не выбрасывает исключений

	    __declspec(dllexport)
		    void KLCONN_CREATECONNECTOR(
                    const wchar_t*      szwProduct,
                    const wchar_t*      szwVersion,
                    KLCONN::Connector** ppConnector,
                    KLERR::Error**		ppError)
		{			
			//Выполняем какие-либо действия
			//.............................
		};
	
	*/

	#define KLCONN_CREATECONNECTOR  KLCONN_CreateConnector

    class Connector;

	typedef void (KLCONN_CALL * CreateConnector)(
                            const wchar_t*      szwProduct,
                            const wchar_t*      szwVersion,                            
                            KLCONN::Connector** ppConnector,
                            KLERR::Error**		ppError);



    /*!
    \brief Главный интерфейс модуля, отвечающего за интеграцию 
        приложений с системой администрирования. 

        Данный интерфейс является точкой входа для системы
        администрирования и предоставляет все требуемые для интеграции
        интерфейсы.

        Интерфейс реализуется библиотекой интеграции
        Интерфейс используется системой администрирования.

        Вызовы методов интерфейса могут производится на разных нитях, но при
        этом сериализуются вызывающей стороной.
    */


    //! Имя компонента "коннектор"
    #define KLCONN_COMPONENT_NAME       L"Connector"
    
    //! Текущая версия компонента "коннектор"
    #define KLCONN_COMPONENT_VERSION    L"1.0.0.0"

    #define KLCONN_MAKE_WELLKNOWN(_product) (_product + L"-" + KLCONN_COMPONENT_NAME)



    class KLSTD_NOVTABLE Connector : public KLSTD::KLBaseQI
    {
    public:
    /*!
        \brief Возвращает указатель на интерфейс, используемый для
            синхронизации настроек приложения.

        \param ppSynchronizer	[out]	указатель на переменную, в которую
            будет записан указатель на интерфейс, используемый для
            синхронизации настроек.

    */
        virtual void CreateSettingsSynchronizer(
			    KLCONN::SettingsSynchronizer ** ppSynchronizer) = 0;

    /*!
      \brief Возвращает указатель на интерфейс, используемый для
            синхронизации политики приложения.

        \param ppSynchronizer	[out]	указатель на переменную, в которую
            будет записан указатель на интерфейс, используемый для
            синхронизации политики приложения (см. "..\prss\prssconst.h").

        Структура политики    
            Структура данных:
                <container1_name>
                 +---<var1_name>=value1 //type1
                 +---<var2_name>=value2 //type2


            Соответствующая ей структура политики:
                <container1_name>                              //PARAMS
                 +---<c_szwSPS_Value>                          //PARAMS_T
                 |          +---<var1_name>                    //PARAMS_T
                 |               +---<c_szwSPS_Value>=value1   //type1
                 |               +---c_szwSPS_Mandatory        //BOOL_T
                 |          +---<var2_name>                    //PARAMS_T
                 |               +---<c_szwSPS_Value>=value2   //type2
                 |               +---c_szwSPS_Mandatory        //BOOL_T
                 +---c_szwSPS_Mandatory                        //BOOL_T

    */
        virtual void CreatePolicySynchronizer(
                KLCONN::SettingsSynchronizer ** ppSynchronizer)  = 0;

    /*!
      \brief Возвращает указатель на интерфейс, используемый для
            синхронизации настроек задач приложения.

        \param ppSynchronizer	[out]	указатель на переменную, в которую
            будет записан указатель на интерфейс, используемый для
            синхронизации настроек задач приложения.
    */
        virtual void CreateTaskSettingsSynchronizer (
			    KLCONN::TaskSettingsSynchronizer ** ppSynchronizer)  = 0;


	/*!
      \brief Возвращает указатель на интерфейс, используемый для
            синхронизации текущего состояния задач приложения.

        \param ppSynchronizer	[out]	указатель на переменную, в которую
            будет записан указатель на интерфейс, используемый для
            синхронизации текущего состояния задач приложения.
    */
        virtual void CreateTasksSynchronizer (
			    KLCONN::TasksSynchronizer ** ppSynchronizer)  = 0;

    /*!
      \brief Возвращает указатель на интерфейс, используемый для
            синхронизации текущего состояния приложения.

        \param ppSynchronizer	[out]	указатель на переменную, в которую
            будет записан указатель на интерфейс, используемый для
            синхронизации текущего состояния приложения.
    */
        virtual void CreateAppSynchronizer(
                KLCONN::AppSynchronizer** connector)  = 0;

    /*!
         \brief	Данный метод вызывается после окончаниии инициализации 
         системы администрирования. Библиотека интеграции получает 
         указатель на KLCONN::Notifier и может вызывать его методы.
         После вызова этого метода система администрирования начинает
         использовать интерфейсы, полученные с помощью перечисленных выше
         методов. Количество вызовов StartIntegration строго равно
         количеству вызовов StopIntegration.

         \param	pNotifier [in] указатель на 
    */
        virtual void StartIntegration(KLCONN::Notifier*   pNotifier) = 0;
        
    /*!
         Данный метод вызывается перед началом деинициализации системы 
         администрирования. После выхода из этого метода библиотека 
         интеграции не должны вызывать методы интерфейса KLCONN::Notifier.
         После вызова данного метода система администрирования прекращает
         использовать интерфейсы, полученные с помощью перечисленных выше
         методов. Количество вызовов StopIntegration строго равно 
         количеству вызовов StartIntegration.
         
         \exception данный метод не выбрасывает исключений.
    */
        KLSTD_NOTHROW virtual void StopIntegration() throw() = 0;
    };
    
}


#endif // KLCONN_CONNECTOR_H


