/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_comphelper.hxx"

#include <comphelper/uieventslogger.hxx>
#include <boost/shared_ptr.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/XTerminateListener.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/logging/LogLevel.hpp>
#include <com/sun/star/logging/XCsvLogFormatter.hpp>
#include <com/sun/star/logging/XLogHandler.hpp>
#include <com/sun/star/logging/XLogger.hpp>
#include <com/sun/star/logging/XLoggerPool.hpp>
#include <com/sun/star/oooimprovement/XCoreController.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/util/XStringSubstitution.hpp>
#include <comphelper/configurationhelper.hxx>
#include <comphelper/processfactory.hxx>
#include <map>
#include <osl/file.hxx>
#include <osl/mutex.hxx>
#include <osl/time.h>
#include <rtl/ustrbuf.hxx>


using namespace com::sun::star::beans;
using namespace com::sun::star::frame;
using namespace com::sun::star::lang;
using namespace com::sun::star::logging;
using namespace com::sun::star::oooimprovement;
using namespace com::sun::star::uno;
using namespace com::sun::star::util;
using namespace cppu;
using namespace osl;
using namespace rtl;
using namespace std;


namespace
{
    static void lcl_SetupOriginAppAbbr(map<OUString, OUString>& abbrs)
    {
        abbrs[OUString::createFromAscii("com.sun.star.text.TextDocument")] = OUString::createFromAscii("W"); // Writer
        abbrs[OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument")] = OUString::createFromAscii("C"); // Calc
        abbrs[OUString::createFromAscii("com.sun.star.presentation.PresentationDocument")] = OUString::createFromAscii("I"); // Impress
        abbrs[OUString::createFromAscii("com.sun.star.drawing.DrawingDocument")] = OUString::createFromAscii("D"); // Draw
    };

    static void lcl_SetupOriginWidgetAbbr(map<OUString,OUString>& abbrs)
    {
        abbrs[OUString::createFromAscii("ButtonToolbarController")] = OUString::createFromAscii("0");
        abbrs[OUString::createFromAscii("ComplexToolbarController")] = OUString::createFromAscii("1");
        abbrs[OUString::createFromAscii("ControlMenuController")] = OUString::createFromAscii("2");
        abbrs[OUString::createFromAscii("FontMenuController")] = OUString::createFromAscii("3");
        abbrs[OUString::createFromAscii("FontSizeMenuController")] = OUString::createFromAscii("4");
        abbrs[OUString::createFromAscii("FooterMenuController")] = OUString::createFromAscii("5");
        abbrs[OUString::createFromAscii("GenericToolbarController")] = OUString::createFromAscii("6");
        abbrs[OUString::createFromAscii("HeaderMenuController")] = OUString::createFromAscii("7");
        abbrs[OUString::createFromAscii("LanguageSelectionMenuController")] = OUString::createFromAscii("8");
        abbrs[OUString::createFromAscii("LangSelectionStatusbarController")] = OUString::createFromAscii("9");
        abbrs[OUString::createFromAscii("MacrosMenuController")] = OUString::createFromAscii("10");
        abbrs[OUString::createFromAscii("MenuBarManager")] = OUString::createFromAscii("11");
        abbrs[OUString::createFromAscii("NewMenuController")] = OUString::createFromAscii("12");
        abbrs[OUString::createFromAscii("ObjectMenuController")] = OUString::createFromAscii("13");
        abbrs[OUString::createFromAscii("RecentFilesMenuController")] = OUString::createFromAscii("14");
        abbrs[OUString::createFromAscii("ToolbarsMenuController")] = OUString::createFromAscii("15");
        abbrs[OUString::createFromAscii("SfxToolBoxControl")] = OUString::createFromAscii("16");
        abbrs[OUString::createFromAscii("SfxAsyncExec")] = OUString::createFromAscii("17");
        abbrs[OUString::createFromAscii("AcceleratorExecute")] = OUString::createFromAscii("18");
    };
}

namespace comphelper
{
    // declaration of implementation
    class UiEventsLogger_Impl;
    class UiEventsLogger_Impl : public UiEventsLogger
    {
        private:
            //typedefs and friends
            friend class UiEventsLogger;
            typedef UiEventsLogger_Impl* ptr;

            // instance methods and data
            UiEventsLogger_Impl();
            void initializeLogger();
            void logDispatch(const ::com::sun::star::util::URL& url,
                const Sequence<PropertyValue>& args);
            void logRotated();
            void logVcl(const ::rtl::OUString& parent_id,
                sal_Int32 window_type,
                const ::rtl::OUString& id,
                const ::rtl::OUString& method,
                const ::rtl::OUString& param);
            void rotate();
            void hotRotate();
            void prepareLogHandler();
            void checkIdleTimeout();
            OUString getCurrentPath();
            OUString getRotatedPath();
            void disposing();

            bool m_Active;
            TimeValue m_LastLogEventTime;
            const OUString m_LogPath;
            const TimeValue m_IdleTimeout;
            sal_Int32 m_SessionLogEventCount;
            Reference<XLogger> m_Logger;
            Reference<XLogHandler> m_LogHandler;
            Reference<XCsvLogFormatter> m_Formatter;
            map<OUString, OUString> m_OriginAppAbbr;
            map<OUString, OUString> m_OriginWidgetAbbr;


            // static methods and data
            static ptr getInstance();
            static void prepareMutex();
            static bool shouldActivate();
            static bool getEnabledFromCoreController();
            static bool getEnabledFromCfg();
            static TimeValue getIdleTimeoutFromCfg();
            static OUString getLogPathFromCfg();
            static sal_Int32 findIdx(const Sequence<PropertyValue>& args, const OUString& key);

            static ptr instance;
            static Mutex * singleton_mutex;
            static const sal_Int32 COLUMNS;
            static const OUString CFG_ENABLED;
            static const OUString CFG_IDLETIMEOUT;
            static const OUString CFG_LOGGING;
            static const OUString CFG_LOGPATH;
            static const OUString CFG_OOOIMPROVEMENT;
            static const OUString ETYPE_DISPATCH;
            static const OUString ETYPE_ROTATED;
            static const OUString ETYPE_VCL;
            static const OUString CSSL_CSVFORMATTER;
            static const OUString CSSL_FILEHANDLER;
            static const OUString CSSL_LOGGERPOOL;
            static const OUString CSSO_CORECONTROLLER;
            static const OUString CSST_JOBEXECUTOR;
            static const OUString CSSU_PATHSUB;
            static const OUString LOGGERNAME;
            static const OUString LOGORIGINAPP;
            static const OUString LOGORIGINWIDGET;
            static const OUString UNKNOWN_ORIGIN;
            static const OUString FN_CURRENTLOG;
            static const OUString FN_ROTATEDLOG;
            static const OUString LOGROTATE_EVENTNAME;
            static const OUString URL_UNO;
            static const OUString URL_SPECIAL;
            static const OUString URL_FILE;
    };
}

namespace comphelper
{
    // consts
    const sal_Int32 UiEventsLogger_Impl::COLUMNS = 9;
    const OUString UiEventsLogger_Impl::CFG_ENABLED = OUString::createFromAscii("EnablingAllowed");
    const OUString UiEventsLogger_Impl::CFG_IDLETIMEOUT = OUString::createFromAscii("IdleTimeout");
    const OUString UiEventsLogger_Impl::CFG_LOGGING = OUString::createFromAscii("/org.openoffice.Office.Logging");
    const OUString UiEventsLogger_Impl::CFG_LOGPATH = OUString::createFromAscii("LogPath");
    const OUString UiEventsLogger_Impl::CFG_OOOIMPROVEMENT = OUString::createFromAscii("OOoImprovement");

    const OUString UiEventsLogger_Impl::CSSL_CSVFORMATTER = OUString::createFromAscii("com.sun.star.logging.CsvFormatter");
    const OUString UiEventsLogger_Impl::CSSL_FILEHANDLER = OUString::createFromAscii("com.sun.star.logging.FileHandler");
    const OUString UiEventsLogger_Impl::CSSL_LOGGERPOOL = OUString::createFromAscii("com.sun.star.logging.LoggerPool");
    const OUString UiEventsLogger_Impl::CSSO_CORECONTROLLER = OUString::createFromAscii("com.sun.star.oooimprovement.CoreController");
    const OUString UiEventsLogger_Impl::CSSU_PATHSUB = OUString::createFromAscii("com.sun.star.util.PathSubstitution");

    const OUString UiEventsLogger_Impl::ETYPE_DISPATCH = OUString::createFromAscii("dispatch");
    const OUString UiEventsLogger_Impl::ETYPE_ROTATED = OUString::createFromAscii("rotated");
    const OUString UiEventsLogger_Impl::ETYPE_VCL = OUString::createFromAscii("vcl");

    const OUString UiEventsLogger_Impl::LOGGERNAME = OUString::createFromAscii("org.openoffice.oooimprovement.Core.UiEventsLogger");
    const OUString UiEventsLogger_Impl::LOGORIGINWIDGET = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginWidget");
    const OUString UiEventsLogger_Impl::LOGORIGINAPP = OUString::createFromAscii("comphelper.UiEventsLogger.LogOriginApp");

    const OUString UiEventsLogger_Impl::UNKNOWN_ORIGIN = OUString::createFromAscii("unknown origin");
    const OUString UiEventsLogger_Impl::FN_CURRENTLOG = OUString::createFromAscii("Current");
    const OUString UiEventsLogger_Impl::FN_ROTATEDLOG = OUString::createFromAscii("OOoImprove");
    const OUString UiEventsLogger_Impl::LOGROTATE_EVENTNAME = OUString::createFromAscii("onOOoImprovementLogRotated");

    const OUString UiEventsLogger_Impl::URL_UNO = OUString::createFromAscii(".uno:");
    const OUString UiEventsLogger_Impl::URL_SPECIAL = OUString::createFromAscii(".special:");
    const OUString UiEventsLogger_Impl::URL_FILE = OUString::createFromAscii("file:");


    // public UiEventsLogger interface
    sal_Bool UiEventsLogger::isEnabled()
    {
        if ( UiEventsLogger_Impl::getEnabledFromCfg() )
        {
            try {
                UiEventsLogger_Impl::prepareMutex();
                Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
                return UiEventsLogger_Impl::getInstance()->m_Active;
            } catch(...) { return false; } // never throws
        } // if ( )
        return sal_False;
    }

    sal_Int32 UiEventsLogger::getSessionLogEventCount()
    {
        try {
            UiEventsLogger_Impl::prepareMutex();
            Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
            return UiEventsLogger_Impl::getInstance()->m_SessionLogEventCount;
        } catch(...) { return 0; } // never throws
    }

    void UiEventsLogger::appendDispatchOrigin(
        Sequence<PropertyValue>& args,
        const OUString& originapp,
        const OUString& originwidget)
    {
        sal_Int32 old_length = args.getLength();
        args.realloc(old_length+2);
        args[old_length].Name = UiEventsLogger_Impl::LOGORIGINAPP;
        args[old_length].Value = static_cast<Any>(originapp);
        args[old_length+1].Name = UiEventsLogger_Impl::LOGORIGINWIDGET;
        args[old_length+1].Value = static_cast<Any>(originwidget);
    }

    Sequence<PropertyValue> UiEventsLogger::purgeDispatchOrigin(
        const Sequence<PropertyValue>& args)
    {
        Sequence<PropertyValue> result(args.getLength());
        sal_Int32 target_idx=0;
        for(sal_Int32 source_idx=0; source_idx<args.getLength(); source_idx++)
            if(args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINAPP
                && args[source_idx].Name != UiEventsLogger_Impl::LOGORIGINWIDGET)
                result[target_idx++] = args[source_idx];
        result.realloc(target_idx);
        return result;
    }

    void UiEventsLogger::logDispatch(
        const URL& url,
        const Sequence<PropertyValue>& args)
    {
        try {
            UiEventsLogger_Impl::prepareMutex();
            Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
            UiEventsLogger_Impl::getInstance()->logDispatch(url, args);
        } catch(...) { } // never throws
    }

    void UiEventsLogger::logVcl(
        const OUString& parent_id,
        sal_Int32 window_type,
        const OUString& id,
        const OUString& method,
        const OUString& param)
    {
        try {
            UiEventsLogger_Impl::prepareMutex();
            Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
            UiEventsLogger_Impl::getInstance()->logVcl(parent_id, window_type, id, method, param);
        } catch(...) { } // never throws
    }

    void UiEventsLogger::logVcl(
        const OUString& parent_id,
        sal_Int32 window_type,
        const OUString& id,
        const OUString& method,
        sal_Int32 param)
    {
        OUStringBuffer buf;
        UiEventsLogger::logVcl(parent_id, window_type, id, method, buf.append(param).makeStringAndClear());
    }

    void UiEventsLogger::logVcl(
        const OUString& parent_id,
        sal_Int32 window_type,
        const OUString& id,
        const OUString& method)
    {
        OUString empty;
        UiEventsLogger::logVcl(parent_id, window_type, id, method, empty);
    }

    void UiEventsLogger::disposing()
    {
        // we dont want to create an instance just to dispose it
        UiEventsLogger_Impl::prepareMutex();
        Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
        if(UiEventsLogger_Impl::instance!=UiEventsLogger_Impl::ptr())
            UiEventsLogger_Impl::getInstance()->disposing();
    }

    void UiEventsLogger::reinit()
    {
        UiEventsLogger_Impl::prepareMutex();
        Guard<Mutex> singleton_guard(UiEventsLogger_Impl::singleton_mutex);
        if(UiEventsLogger_Impl::instance)
        {
            UiEventsLogger_Impl::instance->disposing();
            delete UiEventsLogger_Impl::instance;
            UiEventsLogger_Impl::instance = NULL;
        }
    }

    // private UiEventsLogger_Impl methods
    UiEventsLogger_Impl::UiEventsLogger_Impl()
        : m_Active(UiEventsLogger_Impl::shouldActivate())
        , m_LogPath(UiEventsLogger_Impl::getLogPathFromCfg())
        , m_IdleTimeout(UiEventsLogger_Impl::getIdleTimeoutFromCfg())
        , m_SessionLogEventCount(0)
    {
        lcl_SetupOriginAppAbbr(m_OriginAppAbbr);
        lcl_SetupOriginWidgetAbbr(m_OriginWidgetAbbr);
        m_LastLogEventTime.Seconds = m_LastLogEventTime.Nanosec = 0;
        if(m_Active) rotate();
        if(m_Active) initializeLogger();
    }

    void UiEventsLogger_Impl::logDispatch(
        const URL& url,
        const Sequence<PropertyValue>& args)
    {
        if(!m_Active) return;
        if(!url.Complete.match(URL_UNO)
            && !url.Complete.match(URL_FILE)
            && !url.Complete.match(URL_SPECIAL))
        {
            return;
        }
        checkIdleTimeout();

        Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
        logdata[0] = ETYPE_DISPATCH;
        sal_Int32 originapp_idx = findIdx(args, LOGORIGINAPP);
        if(originapp_idx!=-1)
        {
            OUString app;
            args[originapp_idx].Value >>= app;
            map<OUString, OUString>::iterator abbr_it = m_OriginAppAbbr.find(app);
            if(abbr_it != m_OriginAppAbbr.end())
                app = abbr_it->second;
            logdata[1] = app;
        }
        else
            logdata[1] = UNKNOWN_ORIGIN;
        sal_Int32 originwidget_idx = findIdx(args, LOGORIGINWIDGET);
        if(originwidget_idx!=-1)
        {
            OUString widget;
            args[originwidget_idx].Value >>= widget;
            map<OUString, OUString>::iterator widget_it = m_OriginWidgetAbbr.find(widget);
            if(widget_it != m_OriginWidgetAbbr.end())
                widget = widget_it->second;
            logdata[2] = widget;
        }
        else
            logdata[2] = UNKNOWN_ORIGIN;
        if(url.Complete.match(URL_FILE))
            logdata[3] = URL_FILE;
        else
            logdata[3] = url.Main;
        OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
            OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
        m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
        m_SessionLogEventCount++;
    }

    void UiEventsLogger_Impl::logRotated()
    {
        Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
        logdata[0] = ETYPE_ROTATED;
        OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
            OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
        m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
    }

    void UiEventsLogger_Impl::logVcl(
        const OUString& parent_id,
        sal_Int32 window_type,
        const OUString& id,
        const OUString& method,
        const OUString& param)
    {
        if(!m_Active) return;
        checkIdleTimeout();

        OUStringBuffer buf;
        Sequence<OUString> logdata = Sequence<OUString>(COLUMNS);
        logdata[0] = ETYPE_VCL;
        logdata[4] = parent_id;
        logdata[5] = buf.append(window_type).makeStringAndClear();
        logdata[6] = id;
        logdata[7] = method;
        logdata[8] = param;
        OSL_TRACE("UiEventsLogger Logging: %s,%s,%s,%s,%s,%s,%s,%s",
            OUStringToOString(logdata[0],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[1],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[2],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[3],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[4],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[5],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[6],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[7],RTL_TEXTENCODING_UTF8).getStr(),
            OUStringToOString(logdata[8],RTL_TEXTENCODING_UTF8).getStr());
        m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata));
        m_SessionLogEventCount++;
    }

    void UiEventsLogger_Impl::rotate()
    {
        FileBase::RC result = File::move(getCurrentPath(), getRotatedPath());
        if(result!=FileBase::E_None && result!=FileBase::E_NOENT)
            m_Active = false;
    }

    void UiEventsLogger_Impl::hotRotate()
    {
        logRotated();
        m_Logger->removeLogHandler(m_LogHandler);
        m_LogHandler = NULL;
        rotate();
        prepareLogHandler();
        if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is())
        {
            m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY));
            m_LogHandler->setLevel(LogLevel::ALL);
            m_Logger->addLogHandler(m_LogHandler);
        }
        else
            m_Active = false;
    }

    void UiEventsLogger_Impl::prepareLogHandler()
    {
        Reference<XMultiServiceFactory> sm = getProcessServiceFactory();

        Sequence<Any> init_args = Sequence<Any>(1);
        init_args[0] = static_cast<Any>(getCurrentPath());
        Reference< XInterface > temp =
            sm->createInstanceWithArguments(CSSL_FILEHANDLER, init_args);
        m_LogHandler = Reference<XLogHandler>(temp, UNO_QUERY);
    }

    void UiEventsLogger_Impl::checkIdleTimeout()
    {
        TimeValue now;
        osl_getSystemTime(&now);
        if(now.Seconds - m_LastLogEventTime.Seconds > m_IdleTimeout.Seconds && m_SessionLogEventCount>0)
            hotRotate();
        m_LastLogEventTime = now;
    }

    OUString UiEventsLogger_Impl::getCurrentPath()
    {
        OUStringBuffer current_path(m_LogPath);
        current_path.appendAscii("/");
        current_path.append(FN_CURRENTLOG);
        current_path.appendAscii(".csv");
        return current_path.makeStringAndClear();
    }

    OUString UiEventsLogger_Impl::getRotatedPath()
    {
        OUStringBuffer rotated_path(m_LogPath);
        rotated_path.appendAscii("/");
        rotated_path.append(FN_ROTATEDLOG);
        rotated_path.appendAscii("-");
        {
            // ISO 8601
            char tsrotated_pathfer[20];
            oslDateTime now;
            TimeValue now_tv;
            osl_getSystemTime(&now_tv);
            osl_getDateTimeFromTimeValue(&now_tv, &now);
            const size_t rotated_pathfer_size = sizeof(tsrotated_pathfer);
            snprintf(tsrotated_pathfer, rotated_pathfer_size, "%04i-%02i-%02iT%02i_%02i_%02i",
                now.Year,
                now.Month,
                now.Day,
                now.Hours,
                now.Minutes,
                now.Seconds);
            rotated_path.appendAscii(tsrotated_pathfer);
            rotated_path.appendAscii(".csv");
        }
        return rotated_path.makeStringAndClear();
    }

    void UiEventsLogger_Impl::initializeLogger()
    {
        Reference<XMultiServiceFactory> sm = getProcessServiceFactory();

        // getting the Core Uno proxy object 
        // It will call disposing and make sure we clear all our references
        {
            Reference<XTerminateListener> xCore(
                sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.Core")),
                UNO_QUERY);
            Reference<XDesktop> xDesktop(
                sm->createInstance(OUString::createFromAscii("com.sun.star.frame.Desktop")),
                UNO_QUERY);
            if(!(xCore.is() && xDesktop.is()))
            {
                m_Active = false;
                return;
            }
            xDesktop->addTerminateListener(xCore);
        }
        // getting the LoggerPool
        Reference<XLoggerPool> pool;
        {
            Reference<XInterface> temp =
                sm->createInstance(CSSL_LOGGERPOOL);
            pool = Reference<XLoggerPool>(temp, UNO_QUERY);
        }

        // getting the Logger
        m_Logger = pool->getNamedLogger(LOGGERNAME);

        // getting the FileHandler
        prepareLogHandler();

        // getting the Formatter
        {
            Reference<XInterface> temp =
                sm->createInstance(CSSL_CSVFORMATTER);
            m_Formatter = Reference<XCsvLogFormatter>(temp, UNO_QUERY);
        }

        if(m_Formatter.is() && m_LogHandler.is() && m_Logger.is())
        {
            Sequence<OUString> columns = Sequence<OUString>(COLUMNS);
            columns[0] = OUString::createFromAscii("eventtype");
            columns[1] = OUString::createFromAscii("originapp");
            columns[2] = OUString::createFromAscii("originwidget");
            columns[3] = OUString::createFromAscii("uno url");
            columns[4] = OUString::createFromAscii("parent id");
            columns[5] = OUString::createFromAscii("window type");
            columns[6] = OUString::createFromAscii("id");
            columns[7] = OUString::createFromAscii("method");
            columns[8] = OUString::createFromAscii("parameter");
            m_Formatter->setColumnnames(columns);
            m_LogHandler->setFormatter(Reference<XLogFormatter>(m_Formatter, UNO_QUERY));
            m_Logger->setLevel(LogLevel::ALL);
            m_LogHandler->setLevel(LogLevel::ALL);
            m_Logger->addLogHandler(m_LogHandler);
        }
        else
            m_Active = false;
    }

    // private static UiEventsLogger_Impl 
    bool UiEventsLogger_Impl::shouldActivate()
    {
        return getEnabledFromCfg() && getEnabledFromCoreController();
    }

    OUString UiEventsLogger_Impl::getLogPathFromCfg()
    {
        OUString result;
        Reference<XMultiServiceFactory> sm = getProcessServiceFactory();

        ConfigurationHelper::readDirectKey(
            sm,
            CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_LOGPATH,
            ConfigurationHelper::E_READONLY
        ) >>= result;

        Reference<XStringSubstitution> path_sub(
            sm->createInstance(CSSU_PATHSUB),
            UNO_QUERY);
        if(path_sub.is())
            result = path_sub->substituteVariables(result, sal_False);
        return result;
    }

    TimeValue UiEventsLogger_Impl::getIdleTimeoutFromCfg()
    {
        sal_Int32 timeoutminutes = 360;
        Reference<XMultiServiceFactory> sm = getProcessServiceFactory();

        ConfigurationHelper::readDirectKey(
            sm,
            CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_IDLETIMEOUT,
            ConfigurationHelper::E_READONLY
        ) >>= timeoutminutes;
        TimeValue result;
        result.Seconds = static_cast<sal_uInt32>(timeoutminutes)*60;
        result.Nanosec = 0;
        return result;
    }

    bool UiEventsLogger_Impl::getEnabledFromCfg()
    {
        sal_Bool result = false;
        Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
        ConfigurationHelper::readDirectKey(
            sm,
            CFG_LOGGING, CFG_OOOIMPROVEMENT, CFG_ENABLED,
            ::comphelper::ConfigurationHelper::E_READONLY
        ) >>= result;
        return result;
    }

    bool UiEventsLogger_Impl::getEnabledFromCoreController()
    {
        Reference<XMultiServiceFactory> sm = getProcessServiceFactory();
        Reference<XCoreController> core_c(
            sm->createInstance(OUString::createFromAscii("com.sun.star.oooimprovement.CoreController")),
            UNO_QUERY);
        if(!core_c.is()) return false;
        return core_c->enablingUiEventsLoggerAllowed(1);
    }

    UiEventsLogger_Impl::ptr UiEventsLogger_Impl::instance = UiEventsLogger_Impl::ptr();
    UiEventsLogger_Impl::ptr UiEventsLogger_Impl::getInstance()
    {
        if(instance == NULL)
            instance = UiEventsLogger_Impl::ptr(new UiEventsLogger_Impl());
        return instance;
    }

    Mutex * UiEventsLogger_Impl::singleton_mutex = NULL;
    void UiEventsLogger_Impl::prepareMutex()
    {
        if(singleton_mutex == NULL)
        {
            Guard<Mutex> global_guard(Mutex::getGlobalMutex());
            if(singleton_mutex == NULL)
                singleton_mutex = new Mutex();
        }
    }

    sal_Int32 UiEventsLogger_Impl::findIdx(const Sequence<PropertyValue>& args, const OUString& key)
    {
        for(sal_Int32 i=0; i<args.getLength(); i++)
            if(args[i].Name == key)
                return i;
        return -1;
    }

    void UiEventsLogger_Impl::disposing()
    {
        m_Active = false;
        m_Logger.clear() ;
        m_LogHandler.clear();
        m_Formatter.clear();
    }
}
