/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/audio_device/win/audio_device_utility_win.h"

#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/trace.h"

#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#define STRING_MAX_SIZE 256

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);

namespace webrtc
{

// ============================================================================
//                            Construction & Destruction
// ============================================================================

// ----------------------------------------------------------------------------
//  AudioDeviceUtilityWindows() - ctor
// ----------------------------------------------------------------------------

AudioDeviceUtilityWindows::AudioDeviceUtilityWindows(const int32_t id) :
    _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
    _id(id),
    _lastError(AudioDeviceModule::kAdmErrNone)
{
    WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, id, "%s created", __FUNCTION__);
}

// ----------------------------------------------------------------------------
//  AudioDeviceUtilityWindows() - dtor
// ----------------------------------------------------------------------------

AudioDeviceUtilityWindows::~AudioDeviceUtilityWindows()
{
    WEBRTC_TRACE(kTraceMemory, kTraceAudioDevice, _id, "%s destroyed", __FUNCTION__);
    {
        CriticalSectionScoped lock(&_critSect);

        // free stuff here...
    }

    delete &_critSect;
}

// ============================================================================
//                                     API
// ============================================================================

// ----------------------------------------------------------------------------
//  Init()
// ----------------------------------------------------------------------------

int32_t AudioDeviceUtilityWindows::Init()
{

    TCHAR szOS[STRING_MAX_SIZE];

    if (GetOSDisplayString(szOS))
    {
#ifdef _UNICODE
        char os[STRING_MAX_SIZE];
        if (WideCharToMultiByte(CP_UTF8, 0, szOS, -1, os, STRING_MAX_SIZE, NULL, NULL) == 0)
        {
            strncpy(os, "Could not get OS info", STRING_MAX_SIZE);
        }
        WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, _id, "  OS info: %s", os);
#else
        WEBRTC_TRACE(kTraceStateInfo, kTraceAudioDevice, _id, "  OS info: %s", szOS);
#endif
    }

    return 0;
}

// ============================================================================
//                                 Private Methods
// ============================================================================

BOOL AudioDeviceUtilityWindows::GetOSDisplayString(LPTSTR pszOS)
{
    OSVERSIONINFOEX osvi;
    SYSTEM_INFO si;
    PGNSI pGNSI;
    BOOL bOsVersionInfoEx;

    ZeroMemory(&si, sizeof(SYSTEM_INFO));
    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));

    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    // Retrieve information about the current operating system
    //
    bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi);
    if (!bOsVersionInfoEx)
        return FALSE;

    // Parse our OS version string
    //
    if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId && osvi.dwMajorVersion > 4)
    {
        StringCchCopy(pszOS, STRING_MAX_SIZE, TEXT("Microsoft "));

        // Test for the specific product
        //
        //  Operating system	    Version number
        //  --------------------------------------
        //  Windows 7	            6.1
        //  Windows Server 2008 R2	6.1
        //  Windows Server 2008	    6.0
        //  Windows Vista	        6.0
        //  - - - - - - - - - - - - - - - - - - -
        //  Windows Server 2003 R2	5.2
        //  Windows Server 2003	    5.2
        //  Windows XP	            5.1
        //  Windows 2000	        5.0
        //
        //  see http://msdn.microsoft.com/en-us/library/ms724832(VS.85).aspx for details
        //
        if (osvi.dwMajorVersion == 6)
        {
            if (osvi.dwMinorVersion == 0)
            {
                // Windows Vista or Server 2008
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Vista "));
                else
                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Server 2008 " ));
            }

            if (osvi.dwMinorVersion == 1)
            {
                // Windows 7 or Server 2008 R2
                if (osvi.wProductType == VER_NT_WORKSTATION)
                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows 7 "));
                else
                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Server 2008 R2 " ));
            }
        }

        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2)
        {
            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows Server 2003"));
        }

        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
        {
            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows XP "));
            if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Home Edition" ));
            else
                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Professional" ));
        }

        if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
        {
            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT("Windows 2000 "));

            if (osvi.wProductType == VER_NT_WORKSTATION )
            {
                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Professional" ));
            }
            else
            {
                if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Datacenter Server" ));
                else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
                    StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Advanced Server" ));
                else StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( "Server" ));
            }
        }

        // Include service pack (if any)
        //
        if (_tcslen(osvi.szCSDVersion) > 0)
        {
            StringCchCat(pszOS, STRING_MAX_SIZE, TEXT(" "));
            StringCchCat(pszOS, STRING_MAX_SIZE, osvi.szCSDVersion);
        }

        TCHAR buf[80];

        // Include build number
        //
        StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);
        StringCchCat(pszOS, STRING_MAX_SIZE, buf);

        // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise
        //
        pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
        if (NULL != pGNSI)
            pGNSI(&si);
        else
            GetSystemInfo(&si);

        // Add 64-bit or 32-bit for OS versions "later than" Vista
        //
        if (osvi.dwMajorVersion >= 6)
        {
            if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) ||
                (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64))
                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT( ", 64-bit" ));
            else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL )
                StringCchCat(pszOS, STRING_MAX_SIZE, TEXT(", 32-bit"));
        }

        return TRUE;
    }
    else
    {
        return FALSE;
   }
}

}  // namespace webrtc
