// 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.

#include "chrome/browser/memory_details.h"

#include <psapi.h>
#include <stddef.h>
#include <TlHelp32.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/threading/thread_restrictions.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_thread.h"
#include "content/public/common/process_type.h"
#include "ui/base/l10n/l10n_util.h"

using content::BrowserThread;

// Known browsers which we collect details for.
enum BrowserProcess {
  CHROME_BROWSER = 0,
};

MemoryDetails::MemoryDetails() {
  base::FilePath browser_process_path;
  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::ThreadRestrictions::AssertIOAllowed();

  // 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;

    std::unique_ptr<base::ProcessMetrics> metrics =
        base::ProcessMetrics::CreateProcessMetrics(process_handle.Get());
    metrics->GetCommittedKBytes(&info.committed);
    metrics->GetWorkingSetKBytes(&info.working_set);

    // 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.
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&MemoryDetails::CollectChildInfoOnUIThread, this));
}
