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

#include <string>

#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/task_manager/resource_provider.h"
#include "chrome/grit/generated_resources.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image_skia.h"

using base::ASCIIToUTF16;

namespace {

#if defined(OS_MACOSX)
// From task_manager.cc:
// Activity Monitor shows %cpu with one decimal digit -- be
// consistent with that.
const char* kZeroCPUUsage = "0.0";
#else
const char* kZeroCPUUsage = "0";
#endif

class TestResource : public task_manager::Resource {
 public:
  TestResource() : refresh_called_(false) {}

  base::string16 GetTitle() const override {
    return ASCIIToUTF16("test title");
  }
  base::string16 GetProfileName() const override {
    return ASCIIToUTF16("test profile");
  }
  gfx::ImageSkia GetIcon() const override { return gfx::ImageSkia(); }
  base::ProcessHandle GetProcess() const override {
    return base::GetCurrentProcessHandle();
  }
  int GetUniqueChildProcessId() const override {
    // In reality the unique child process ID is not the actual process ID,
    // but for testing purposes it shouldn't make difference.
    return static_cast<int>(base::GetCurrentProcId());
  }
  Type GetType() const override { return RENDERER; }
  bool SupportNetworkUsage() const override { return false; }
  void SetSupportNetworkUsage() override { NOTREACHED(); }
  void Refresh() override { refresh_called_ = true; }
  bool refresh_called() const { return refresh_called_; }
  void set_refresh_called(bool refresh_called) {
    refresh_called_ = refresh_called;
  }

 private:
  bool refresh_called_;
};

}  // namespace

class TaskManagerTest : public testing::Test {
};

TEST_F(TaskManagerTest, Basic) {
  TaskManager task_manager;
  TaskManagerModel* model = task_manager.model_.get();
  EXPECT_EQ(0, model->ResourceCount());
}

TEST_F(TaskManagerTest, Resources) {
  TaskManager task_manager;
  TaskManagerModel* model = task_manager.model_.get();

  TestResource resource1, resource2;

  task_manager.AddResource(&resource1);
  ASSERT_EQ(1, model->ResourceCount());
  EXPECT_TRUE(model->IsResourceFirstInGroup(0));
  EXPECT_EQ(ASCIIToUTF16("test title"), model->GetResourceTitle(0));
  EXPECT_EQ(ASCIIToUTF16("test profile"), model->GetResourceProfileName(0));
  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT),
            model->GetResourceNetworkUsage(0));
  EXPECT_EQ(ASCIIToUTF16(kZeroCPUUsage), model->GetResourceCPUUsage(0));

  task_manager.AddResource(&resource2);  // Will be in the same group.
  ASSERT_EQ(2, model->ResourceCount());
  EXPECT_TRUE(model->IsResourceFirstInGroup(0));
  EXPECT_FALSE(model->IsResourceFirstInGroup(1));
  EXPECT_EQ(ASCIIToUTF16("test title"), model->GetResourceTitle(1));
  EXPECT_EQ(ASCIIToUTF16("test profile"), model->GetResourceProfileName(1));
  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT).c_str(),
            model->GetResourceNetworkUsage(1));
  EXPECT_EQ(ASCIIToUTF16(kZeroCPUUsage), model->GetResourceCPUUsage(1));

  task_manager.RemoveResource(&resource1);
  // Now resource2 will be first in group.
  ASSERT_EQ(1, model->ResourceCount());
  EXPECT_TRUE(model->IsResourceFirstInGroup(0));
  EXPECT_EQ(ASCIIToUTF16("test title"), model->GetResourceTitle(0));
  EXPECT_EQ(ASCIIToUTF16("test profile"), model->GetResourceProfileName(0));
  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_TASK_MANAGER_NA_CELL_TEXT),
            model->GetResourceNetworkUsage(0));
  EXPECT_EQ(ASCIIToUTF16(kZeroCPUUsage), model->GetResourceCPUUsage(0));

  task_manager.RemoveResource(&resource2);
  EXPECT_EQ(0, model->ResourceCount());
}

// Tests that the model is calling Refresh() on its resources.
TEST_F(TaskManagerTest, RefreshCalled) {
  base::MessageLoop loop;
  TaskManager task_manager;
  TaskManagerModel* model = task_manager.model_.get();
  TestResource resource;

  task_manager.AddResource(&resource);
  ASSERT_FALSE(resource.refresh_called());
  model->update_state_ = TaskManagerModel::TASK_PENDING;
  model->Refresh();
  ASSERT_TRUE(resource.refresh_called());
  task_manager.RemoveResource(&resource);
}
