// ==================================================
// Copyright 2013.
// Siemens Product Lifecycle Management Software Inc.
// All Rights Reserved.
// ==================================================

/**
    @file

    This file contains definition for timer functions helper class.
*/

#ifndef BASE_UTILS_TIMER_HXX
#define BASE_UTILS_TIMER_HXX

#include <unidefs.h>
#include <base_utils/ScopedSmPtr.hxx>

#include <base_utils/libbase_utils_exports.h>

/**
   Structure to capture the process times.
*/
typedef struct TIMER_CLOCK_timer_values_s
{ 
    double cpu_time;       /**< Total (User + System) time for this process */
    double child_cpu_time; /**< Total (User + System) time for children processes */
    double real_time;      /**< Total elapsed time */
} TIMER_CLOCK_timer_values_t, *TIMER_CLOCK_timer_values_p_t;

/**
    @brief A simple wrapper over the SYSS CLOCK timer functions.

    @code
    Timer t( true );
    // do something
    cerr << "something took " << t.elapsedString() << endl;
    @endcode
*/
class BASE_UTILS_API Timer
{
public:

    /**
        Constructor.
    */
    Timer(
        logical startNow = true                /**< (I) Specifies when the timer starts */
        );

    /**
        Default destructor.
    */
    ~Timer();

    /**
        Starts timer.
    */
    void start();

    /**
        Stops timer.
    */
    void stop();

    /**
        Resets the timer.

        @note This function does not stop the timer.
    */
    void reset();

    /**
        Returns the elapsed time in seconds for both the real and cpu times ( e.g. "0.998000s cpu, 1.001000s real" ).

        Returns the elapsed time in seconds for both the Central Processing Unit (CPU) and real times.
        <br>The CPU time measures the amount of time for which a central processing unit (CPU) was used, while the real time includes the waiting time for input/output (I/O) operations or entering low-power (idle) mode.
        <br>The output string is in the format "[d+]\.[d+]s cpu,[d+]\.[d+]s real", e.g. "0.998000s cpu, 1.001000s real".

        @note Caller should store the returned value to another pointer because the returned pointer will be affected by the subsequent call made to this API.
    */
    const char* elapsedString() const;

    /**
        Returns the timer values ( CPU, children CPU and real times ).
    */
    void readTimer(
        TIMER_CLOCK_timer_values_t& values     /**< (OF) The output in #TIMER_CLOCK_timer_values_t structure */
        ) const;

    /**
        Constructs a string output for logging.
        <br/>The output string is in the format ">> Global Timer [text], cpu & real, [d+]\.[d+],[d+]\.[d+]",
        e.g. ">> Global Timer text, cpu & real, 0.999000, 1.001000".

        @note Caller must the returned value by calling #MEM_free.

        @code
        char* str = aTimer.logElapsedString("aText");
        Teamcenter::scoped_smptr< char > free_str ( str );
        Teamcenter::Logging::Logger* aLogger =
            Teamcenter::Logging::Logger::getLogger( "Teamcenter.CoreModelGeneral.tc" );
        aLogger->printf( str );
        @endcode
    */
    char* logElapsedString(
        const char* text                        /**< (I) The input text to add for logging */
        ) const;

    /**
        Checks if login timer is enabled, using "TC_LOGIN_TIMER" preference.
    */
    static bool isLoginTimerEnabled();

private:
    /** The time when the Timer instance was created */
    unsigned short m_timer;

    /**
        Variable for timeString
    */
    mutable char m_buffer[128];

    /**
        Private default constructor
    */
    Timer( const Timer& other );

    /**
        Copy constructor
    */
    Timer& operator=( const Timer& other );

    static bool s_logEnabled;
    static bool s_logEnabledChecked;
    static double s_incrementalCpu;
    static double s_incrementalReal;
};

#include <base_utils/libbase_utils_undef.h>
#endif

