//
//  Copyright © 2001 - 2003, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   SystemMonitor.h
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    
//
//  Notes:      
//

#include "StdAfx.h"
#include "SystemMonitor.h"
#include "RegistryKeys.h"

#include <atlbase.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// CSystemMonitor class implementation... starting with public members first.

using namespace N6046RegistryKeys;

CSystemMonitor::CSystemMonitor( void )
{
    m_bEnabled                = false;
    m_ulAutoHealthCheckPeriod = 0UL;

    m_pfnPerformSystemCheck   = NULL;
    m_pvParam                 = NULL;
}

CSystemMonitor::~CSystemMonitor( void )
{
    m_bEnabled                = false;
    m_ulAutoHealthCheckPeriod = 0UL;

    m_pfnPerformSystemCheck   = NULL;
    m_pvParam                 = NULL;
}

bool CSystemMonitor::Configure( PFN_SYSTEM_CHECK    pfnPerformSystemCheck,
                                void               *pvParam )
{
    m_pfnPerformSystemCheck = pfnPerformSystemCheck;
    m_pvParam               = pvParam;

    RestoreFromRegistry();

    ScheduleNextSystemCheck( m_ulAutoHealthCheckPeriod );

    return true;
}

CSystemMonitor::operator HANDLE ( void ) const
{
    return static_cast<HANDLE>( m_Timer );
}

bool CSystemMonitor::CheckSystemAndReSchedule( void )
{
    bool bSuccess = false;          // Assume failure for now.

    // Invoke the installed callback to handle the actual system check.

    if ( m_pfnPerformSystemCheck != NULL )
    {
        try
        {
            bSuccess = ( m_pfnPerformSystemCheck ) ( m_pvParam, NULL, false );
        }
        catch ( ... )
        {
            bSuccess = false;
        }
    }

    // Schedule the next check, if enabled and a valid period is specified.

    ScheduleNextSystemCheck( m_ulAutoHealthCheckPeriod );

    return bSuccess;
}

void CSystemMonitor::Enable( const bool &rbEnable )
{
    m_bEnabled = rbEnable;
}

bool CSystemMonitor::IsEnabled( void ) const
{
    return m_bEnabled;
}

void CSystemMonitor::Set(   const bool          &rbEnable,
                            const unsigned long &rulPeriodMilliseconds,
                            const bool          &rbUpdateRegistry )
{
    m_bEnabled                = rbEnable;
    m_ulAutoHealthCheckPeriod = rulPeriodMilliseconds;

    if ( rbEnable )
    {
        ScheduleNextSystemCheck( m_ulAutoHealthCheckPeriod );
    }
    else
    {
        m_Timer.Cancel();
    }

    if ( rbUpdateRegistry )
    {
        SaveToRegistry();
    }
}

///////////////////////////////////////////////////////////////////////////////
// Private members.

inline
void CSystemMonitor::ScheduleNextSystemCheck( const unsigned long &rulPeriodInMilliseconds )
{
    if ( m_bEnabled && ( rulPeriodInMilliseconds > 0UL ) )
    {
        m_Timer.Set( rulPeriodInMilliseconds, 0UL );
    }
}

inline
void CSystemMonitor::RestoreFromRegistry( void )
{
    CRegKey       Key;

    m_bEnabled                = false;
    m_ulAutoHealthCheckPeriod = 60000UL;
        
    Key.Attach( hKey6046_c );

    if ( Key.Open( hKey6046_c, lpsz6046RegistryKey_c ) == ERROR_SUCCESS )
    {
        DWORD dwValue = 0UL;

        if ( Key.QueryValue( dwValue, lpsz6046CheckPeriodRegistryKey_c ) == ERROR_SUCCESS )
        {
            m_ulAutoHealthCheckPeriod = static_cast<unsigned long>( dwValue );
        }

        if ( Key.QueryValue( dwValue, lpsz6046CheckEnableRegistryKey_c ) == ERROR_SUCCESS )
        {
            m_bEnabled = static_cast<bool>( dwValue != 0 );
        }

        Key.Close();
    }
}

inline
void CSystemMonitor::SaveToRegistry( void )
{
    CRegKey Key;

    Key.Attach( hKey6046_c );

    try
    {
        DWORD dwValue = 0UL;

        if ( Key.Open( hKey6046_c, lpsz6046RegistryKey_c ) != ERROR_SUCCESS )
        {
            throw lpsz6046RegistryKey_c;
        }

        dwValue = static_cast<DWORD>( m_ulAutoHealthCheckPeriod );

        if ( Key.SetValue( dwValue, lpsz6046CheckPeriodRegistryKey_c ) != ERROR_SUCCESS )
        {
            CString FullKey;
            
            FullKey.Format( "%s\\%s", lpsz6046RegistryKey_c, lpsz6046CheckPeriodRegistryKey_c );

            if ( Key.Create( hKey6046_c, static_cast<LPCTSTR>( FullKey ) ) == ERROR_SUCCESS )
            {
                if ( Key.SetValue( dwValue, lpsz6046CheckPeriodRegistryKey_c ) != ERROR_SUCCESS )
                {
                    ASSERT( false );
                }
            }
            else
            {
                ASSERT( false );
            }
        }

        dwValue = static_cast<DWORD>( m_bEnabled ? 1UL : 0UL );

        if ( Key.SetValue( dwValue, lpsz6046CheckEnableRegistryKey_c ) != ERROR_SUCCESS )
        {
            CString FullKey;
            
            FullKey.Format( "%s\\%s", lpsz6046RegistryKey_c, lpsz6046CheckEnableRegistryKey_c );

            if ( Key.Create( hKey6046_c, static_cast<LPCTSTR>( FullKey ) ) == ERROR_SUCCESS )
            {
                if ( Key.SetValue( dwValue, lpsz6046CheckEnableRegistryKey_c ) != ERROR_SUCCESS )
                {
                    ASSERT( false );
                }
            }
            else
            {
                ASSERT( false );
            }
        }
    }
    catch ( LPCTSTR lpszMessage )
    {
        TRACE( _T( "CSystemMonitor::SaveToRegistry(), %s\n" ), lpszMessage );
    }
    catch ( ... )
    {
        TRACE( _T( "CSystemMonitor::SaveToRegistry(), unspecified exception caught\n" ) );
    }

    Key.Close();
}
