// Copyright 2015 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/task_manager/test_task_manager.h"

namespace task_manager {

TestTaskManager::TestTaskManager()
    : handle_(base::kNullProcessHandle),
      pid_(base::kNullProcessId) {
  set_timer_for_testing(
      std::unique_ptr<base::Timer>(new base::MockTimer(true, true)));
}

TestTaskManager::~TestTaskManager() {
}

void TestTaskManager::ActivateTask(TaskId task_id) {
}

bool TestTaskManager::IsTaskKillable(TaskId task_id) {
  return true;
}

void TestTaskManager::KillTask(TaskId task_id) {
}

double TestTaskManager::GetCpuUsage(TaskId task_id) const {
  return 0.0;
}

base::Time TestTaskManager::GetStartTime(TaskId task_id) const {
  return base::Time();
}

base::TimeDelta TestTaskManager::GetCpuTime(TaskId task_id) const {
  return base::TimeDelta();
}

int64_t TestTaskManager::GetPhysicalMemoryUsage(TaskId task_id) const {
  return -1;
}

int64_t TestTaskManager::GetPrivateMemoryUsage(TaskId task_id) const {
  return -1;
}

int64_t TestTaskManager::GetSharedMemoryUsage(TaskId task_id) const {
  return -1;
}

int64_t TestTaskManager::GetSwappedMemoryUsage(TaskId task_id) const {
  return -1;
}

int64_t TestTaskManager::GetGpuMemoryUsage(TaskId task_id,
                                           bool* has_duplicates) const {
  return -1;
}

base::MemoryState TestTaskManager::GetMemoryState(TaskId task_id) const {
  return base::MemoryState::UNKNOWN;
}

int TestTaskManager::GetIdleWakeupsPerSecond(TaskId task_id) const {
  return -1;
}

int TestTaskManager::GetNaClDebugStubPort(TaskId task_id) const {
  return -1;
}

void TestTaskManager::GetGDIHandles(TaskId task_id,
                                    int64_t* current,
                                    int64_t* peak) const {}

void TestTaskManager::GetUSERHandles(TaskId task_id,
                                     int64_t* current,
                                     int64_t* peak) const {}

int TestTaskManager::GetOpenFdCount(TaskId task_id) const {
  return -1;
}

bool TestTaskManager::IsTaskOnBackgroundedProcess(TaskId task_id) const {
  return false;
}

const base::string16& TestTaskManager::GetTitle(TaskId task_id) const {
  return title_;
}

const std::string& TestTaskManager::GetTaskNameForRappor(TaskId task_id) const {
  return rappor_sample_;
}

base::string16 TestTaskManager::GetProfileName(TaskId task_id) const {
  return base::string16();
}

const gfx::ImageSkia& TestTaskManager::GetIcon(TaskId task_id) const {
  return icon_;
}

const base::ProcessHandle& TestTaskManager::GetProcessHandle(
    TaskId task_id) const {
  return handle_;
}

const base::ProcessId& TestTaskManager::GetProcessId(TaskId task_id) const {
  return pid_;
}

Task::Type TestTaskManager::GetType(TaskId task_id) const {
  return Task::UNKNOWN;
}

int TestTaskManager::GetTabId(TaskId task_id) const {
  return -1;
}

int TestTaskManager::GetChildProcessUniqueId(TaskId task_id) const {
  return 0;
}

void TestTaskManager::GetTerminationStatus(TaskId task_id,
                                           base::TerminationStatus* out_status,
                                           int* out_error_code) const {
  DCHECK(out_status);
  DCHECK(out_error_code);

  *out_status = base::TERMINATION_STATUS_STILL_RUNNING;
  *out_error_code = 0;
}

int64_t TestTaskManager::GetNetworkUsage(TaskId task_id) const {
  return -1;
}

int64_t TestTaskManager::GetProcessTotalNetworkUsage(TaskId task_id) const {
  return -1;
}

int64_t TestTaskManager::GetSqliteMemoryUsed(TaskId task_id) const {
  return -1;
}

bool TestTaskManager::GetV8Memory(TaskId task_id,
                                  int64_t* allocated,
                                  int64_t* used) const {
  return false;
}

bool TestTaskManager::GetWebCacheStats(
    TaskId task_id,
    blink::WebCache::ResourceTypeStats* stats) const {
  return false;
}

int TestTaskManager::GetKeepaliveCount(TaskId task_id) const {
  return -1;
}

const TaskIdList& TestTaskManager::GetTaskIdsList() const {
  return ids_;
}

TaskIdList TestTaskManager::GetIdsOfTasksSharingSameProcess(
    TaskId task_id) const {
  TaskIdList result;
  result.push_back(task_id);
  return result;
}

size_t TestTaskManager::GetNumberOfTasksOnSameProcess(TaskId task_id) const {
  return 1;
}

TaskId TestTaskManager::GetTaskIdForWebContents(
    content::WebContents* web_contents) const {
  return -1;
}

base::TimeDelta TestTaskManager::GetRefreshTime() {
  return GetCurrentRefreshTime();
}

int64_t TestTaskManager::GetEnabledFlags() {
  return enabled_resources_flags();
}

}  // namespace task_manager
