// Copyright (c) 2012 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.

// Windows headers must come first.
#include <windows.h>

#include <psapi.h>
#include <stddef.h>
#include <TlHelp32.h>

#include "chrome/browser/memory_details.h"

#include <memory>

#include "base/bind.h"
#include "base/file_version_info.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/process_type.h"
#include "ui/base/l10n/l10n_util.h"

using content::BrowserThread;

MemoryDetails::MemoryDetails() {
  base::FilePath browser_process_path;
  base::PathService::Get(base::FILE_EXE, &browser_process_path);

  ProcessData process;
  process.name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
  process.process_name = browser_process_path.BaseName().value();
  process_data_.push_back(process);
}

ProcessData* MemoryDetails::ChromeBrowser() {
  return &process_data_[0];
}

void MemoryDetails::CollectProcessData(
    const std::vector<ProcessMemoryInformation>& child_info) {
  base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);

  // Clear old data.
  process_data_[0].processes.clear();

  base::win::ScopedHandle snapshot(
      ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
  PROCESSENTRY32 process_entry = {sizeof(PROCESSENTRY32)};
  if (!snapshot.Get()) {
    LOG(ERROR) << "CreateToolhelp32Snapshot failed: " << GetLastError();
    return;
  }
  if (!::Process32First(snapshot.Get(), &process_entry)) {
    LOG(ERROR) << "Process32First failed: " << GetLastError();
    return;
  }
  do {
    base::ProcessId pid = process_entry.th32ProcessID;
    base::win::ScopedHandle process_handle(::OpenProcess(
        PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
    if (!process_handle.IsValid())
      continue;
    if (_wcsicmp(process_data_[0].process_name.c_str(),
                 process_entry.szExeFile) != 0) {
      continue;
    }

    // Get Memory Information.
    ProcessMemoryInformation info;
    info.pid = pid;
    info.process_type = pid == GetCurrentProcessId()
                            ? content::PROCESS_TYPE_BROWSER
                            : content::PROCESS_TYPE_UNKNOWN;

    // Get Version Information.
    info.version = base::ASCIIToUTF16(version_info::GetVersionNumber());
    // Check if this is one of the child processes whose data we collected
    // on the IO thread, and if so copy over that data.
    for (const ProcessMemoryInformation& child : child_info) {
      if (child.pid == info.pid) {
        info.titles = child.titles;
        info.process_type = child.process_type;
        break;
      }
    }

    // Add the process info to our list.
    process_data_[0].processes.push_back(info);
  } while (::Process32Next(snapshot.Get(), &process_entry));

  // Finally return to the browser thread.
  base::PostTaskWithTraits(
      FROM_HERE, {BrowserThread::UI},
      base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));
}
