// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <windows.h>

#include <stdio.h>
#include <tchar.h>
#include <tlhelp32.h>

#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <string>

// List all thread names in a process specified.
BOOL ListProcessThreadNames(DWORD owner_pid);
// Print the error message.
void printError(TCHAR* msg);

// The GetThreadDescription API is available since Windows 10, version 1607.
// The reason why this API is bound in this way rather than just using the
// Windows SDK, is that this API isn't yet available in the SDK that Chrome
// builds with.
// Binding SetThreadDescription API in Chrome can only be done by
// GetProcAddress, rather than the import library.
typedef HRESULT(WINAPI* GETTHREADDESCRIPTION)(HANDLE hThread,
                                              PWSTR* threadDescription);

int main(void) {
  DWORD process_Id;
  std::string user_input;
  while (true) {
    std::cout
        << "\nPlease enter the process Id, or \"quit\" to end the program : ";
    std::getline(std::cin, user_input);
    // Convert the user input to lower case.
    std::transform(user_input.begin(), user_input.end(), user_input.begin(),
                   ::tolower);
    if (user_input == "quit")
      break;
    std::cout << std::endl;
    std::stringstream ss(user_input);
    if (ss >> process_Id) {
      ListProcessThreadNames(process_Id);
    } else {
      std::cout << "Input is invalid" << std::endl;
    }
    std::cout << std::endl;
  }
  return 0;
}

BOOL ListProcessThreadNames(DWORD owner_pid) {
  auto get_thread_description_func =
      reinterpret_cast<GETTHREADDESCRIPTION>(::GetProcAddress(
          ::GetModuleHandle(L"Kernel32.dll"), "GetThreadDescription"));

  if (!get_thread_description_func) {
    printError(TEXT("GetThreadDescription"));
    return (FALSE);
  }

  HANDLE thread_snapshot = INVALID_HANDLE_VALUE;
  // Take a snapshot of all running threads.
  thread_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  if (thread_snapshot == INVALID_HANDLE_VALUE) {
    printError(TEXT("CreateToolhelp32Snapshot"));
    return (FALSE);
  }

  THREADENTRY32 te32;
  te32.dwSize = sizeof(THREADENTRY32);

  // Retrieve information about the first thread, and exit if unsuccessful.
  if (!Thread32First(thread_snapshot, &te32)) {
    printError(TEXT("Thread32First"));
    CloseHandle(thread_snapshot);
    return (FALSE);
  }

  // Walk the thread list of the system, and display ID and name about each
  // thread associated with the process specified.
  std::cout << "thread_ID   thread_name" << std::endl;
  std::multimap<std::wstring, DWORD> name_id_map;
  do {
    if (te32.th32OwnerProcessID == owner_pid) {
      HANDLE thread_handle =
          OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID);
      if (thread_handle) {
        PWSTR data;
        HRESULT hr = get_thread_description_func(thread_handle, &data);
        if (SUCCEEDED(hr)) {
          std::wstring thread_name(data);
          LocalFree(data);
          name_id_map.insert(std::make_pair(thread_name, te32.th32ThreadID));
        } else {
          printError(TEXT("GetThreadDescription"));
        }
        CloseHandle(thread_handle);
      } else {
        printError(TEXT("OpenThread"));
      }
    }
  } while (Thread32Next(thread_snapshot, &te32));

  // Clean up the snapshot object.
  CloseHandle(thread_snapshot);

  // Show all thread ID/name pairs.
  for (auto name_id_pair : name_id_map) {
    std::cout << name_id_pair.second << "\t";
    std::wcout << name_id_pair.first << std::endl;
  }

  return (TRUE);
}

void printError(TCHAR* msg) {
  DWORD eNum;
  TCHAR sysMsg[256];
  TCHAR* p;

  eNum = GetLastError();
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL, eNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), sysMsg,
                256, NULL);

  // Trim the end of the line and terminate it with a null.
  p = sysMsg;
  while ((*p > 31) || (*p == 9))
    ++p;
  do {
    *p-- = 0;
  } while ((p >= sysMsg) && ((*p == '.') || (*p < 33)));

  // Display the message.
  _tprintf(TEXT("\n  WARNING: %s failed with error %d (%s)"), msg, eNum,
           sysMsg);
}
