#include <windows.h>
#include <assert.h>
#include <psapi.h>
#include <stdio.h>
#include <tchar.h>
#include <time.h>
#include <tlhelp32.h>
#include "Shlwapi.h"

#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "shlwapi.lib")

int gQueryInterval = 5; // seconds
time_t gDuration = 0;   // seconds
LPTSTR gCommandLine;

HRESULT ProcessArgs(int argc, TCHAR *argv[]);
HRESULT PrintUsage();
void UseImage(void (functionForQueryType(HANDLE)));
void QueryContinuously(HANDLE hProcess);
int EvalProcesses(HANDLE hProcess);
time_t ElapsedTime(time_t startTime);

int __cdecl _tmain (int argc, TCHAR *argv[])
{
    HRESULT result = ProcessArgs(argc, argv);
    if (FAILED(result))
        return result;

    UseImage(QueryContinuously);
    return S_OK;
}

HRESULT ProcessArgs(int argc, TCHAR *argv[])
{
    LPTSTR argument;
    for( int count = 1; count < argc; count++ ) {
        argument = argv[count] ;
        if (wcsstr(argument, _T("-h")) || wcsstr(argument, _T("--help")))
            return PrintUsage();
        else if (wcsstr(argument, _T("--exe"))) {
            gCommandLine = argv[++count];
        } else if (wcsstr(argument, _T("-i")) || 
            wcsstr(argument, _T("--interval"))) {
            gQueryInterval = _wtoi(argv[++count]);
            if (gQueryInterval < 1) {
                printf("ERROR: invalid interval\n");
                return E_INVALIDARG;
            }
        } else if (wcsstr(argument, _T("-d")) ||
            wcsstr(argument, _T("--duration"))) {
            gDuration = _wtoi(argv[++count]);
            if (gDuration < 1) {
                printf("ERROR: invalid duration\n");
                return E_INVALIDARG;
            }
        } else {
            _tprintf(_T("ERROR: unrecognized argument \"%s\"\n"), (LPCTSTR)argument);
            return PrintUsage();
        }
    }
    if (argc < 2 || !wcslen(gCommandLine) ) {
        printf("ERROR: executable path is required\n");
        return PrintUsage();
    }
    return S_OK;
}

HRESULT PrintUsage()
{
    printf("record-memory-win --exe EXE_PATH\n");
    printf("    Launch an executable and print the memory usage (in Private Bytes)\n");
    printf("    of the process.\n\n");
    printf("Usage:\n");
    printf("-h [--help]         : Print usage\n");
    printf("--exe arg           : Launch specified image.  Required\n");
    printf("-i [--interval] arg : Print memory usage every arg seconds.  Default: 5 seconds\n");
    printf("-d [--duration] arg : Run for up to arg seconds.  Default: no limit\n\n");
    printf("Examples:\n");
    printf("    record-memory-win --exe \"C:\\Program Files\\Safari\\Safari.exe /newprocess\"\n");
    printf("    record-memory-win --exe \"Safari.exe /newprocess\" -i 10 -d 7200\n");
    printf("    NOTE: Close all other browser intances to ensure launching in a new process\n");
    printf("          Or, pass the /newprocess (or equivalent) argument to the browser\n");
    return E_FAIL;
}

unsigned int getMemoryInfo(DWORD processID)
{
    unsigned int memInfo = 0;
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS_EX pmc;

    hProcess = OpenProcess(  PROCESS_QUERY_INFORMATION |
                                    PROCESS_VM_READ,
                                    FALSE, processID );
    if (NULL == hProcess)
        return 0;

    if (GetProcessMemoryInfo( hProcess, (PPROCESS_MEMORY_COUNTERS)&pmc, sizeof(pmc))) {
        memInfo = (pmc.PrivateUsage);
    }

    CloseHandle( hProcess );
    return memInfo;
}

void printProcessInfo(DWORD processID)
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
   
    // Get a handle to the process.
    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.
    if (NULL != hProcess) {
        HMODULE hMod;       // An array that receives the list of module handles.
        DWORD cbNeeded;     //The number of bytes required to store all module handles in the Module array

        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
            GetModuleBaseName(hProcess, hMod, szProcessName, 
                               sizeof(szProcessName)/sizeof(TCHAR));
        }
    }

    // Print the process name and identifier of matching strings, ignoring case
    _tprintf(TEXT("%s  (PID: %u)\n"), szProcessName, processID);
    
    // Release the handle to the process.
    CloseHandle( hProcess );
}

int evalProcesses(HANDLE hProcess)
{
    if (NULL == hProcess)
        return 0;

    unsigned int totalMemUsage = 0;
    DWORD processID = GetProcessId(hProcess);
  
    HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    PROCESSENTRY32 processEntry = { 0 };
    processEntry.dwSize = sizeof(PROCESSENTRY32);

    // Retrieves information about the first process encountered in a system snapshot
    if(Process32First(hProcessSnapshot, &processEntry)) {
        do {
            // if th32processID = processID, we are the parent process!  
            // if th32ParentProcessID = processID, we are a child process!
            if ((processEntry.th32ProcessID == processID) || (processEntry.th32ParentProcessID == processID)) {
                unsigned int procMemUsage = 0;
                // Record parent process memory
                procMemUsage = getMemoryInfo(processEntry.th32ProcessID);
                totalMemUsage += procMemUsage;
            }
          // Retrieves information about the next process recorded in a system snapshot.   
        } while(Process32Next(hProcessSnapshot, &processEntry));
    }

    CloseHandle(hProcessSnapshot);
    return totalMemUsage;
}


void UseImage(void (functionForQueryType(HANDLE)))
{
    STARTUPINFO si = {0};
    si.cb = sizeof(STARTUPINFO);
    PROCESS_INFORMATION pi = {0};

    // Start the child process. 
    if(!CreateProcess( NULL,   // No module name (use command line)
        gCommandLine,        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi ))          // Pointer to PROCESS_INFORMATION structure
        printf("CreateProcess failed (%d)\n", GetLastError());
    else {
        printf("Created process with id: %d\n", pi.dwProcessId);
        functionForQueryType(pi.hProcess);
        // Close process and thread handles. 
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }
}

void QueryContinuously(HANDLE hProcess)
{
    Sleep(2000); // give the process some time to launch
    bool pastDuration = false;
    time_t startTime = time(NULL);
    unsigned int memUsage = evalProcesses(hProcess);
    while(memUsage && !pastDuration) {
        printf( "%u\n", memUsage );
        Sleep(gQueryInterval*1000);
        memUsage = evalProcesses(hProcess);
        pastDuration = gDuration > 0 ? ElapsedTime(startTime) > gDuration : false;
    } 
}

// returns elapsed time in seconds
time_t ElapsedTime(time_t startTime)
{
    time_t currentTime = time(NULL);
    return currentTime - startTime;
}
