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

#ifndef CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
#define CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_

#include <map>
#include <vector>

#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "base/timer/timer.h"
#include "chrome/browser/renderer_host/web_cache_manager.h"
#include "chrome/browser/task_manager/resource_provider.h"
#include "chrome/browser/ui/host_desktop.h"
#include "content/public/common/gpu_memory_stats.h"
#include "third_party/WebKit/public/web/WebCache.h"

class PrefRegistrySimple;
class TaskManagerModel;
class TaskManagerModelGpuDataManagerObserver;

namespace base {
class ProcessMetrics;
}

namespace content {
class WebContents;
}

namespace extensions {
class Extension;
}

namespace gfx {
class ImageSkia;
}

namespace net {
class URLRequest;
}

// This class is a singleton.
class TaskManager {
 public:
  static void RegisterPrefs(PrefRegistrySimple* registry);

  // Returns true if the process at the specified index is the browser process.
  bool IsBrowserProcess(int index) const;

  // Terminates the process at the specified index.
  void KillProcess(int index);

  // Activates the browser tab associated with the process in the specified
  // index.
  void ActivateProcess(int index);

  // These methods are invoked by the resource providers to add/remove resources
  // to the Task Manager. Note that the resources are owned by the
  // ResourceProviders and are not valid after StopUpdating() has been called
  // on the ResourceProviders.
  void AddResource(task_manager::Resource* resource);
  void RemoveResource(task_manager::Resource* resource);

  void OnWindowClosed();

  // Invoked when a change to a resource has occurred that should cause any
  // observers to completely refresh themselves (for example, the creation of
  // a background resource in a process). Results in all observers receiving
  // OnModelChanged() events.
  void ModelChanged();

  // Returns the singleton instance (and initializes it if necessary).
  static TaskManager* GetInstance();

  TaskManagerModel* model() const { return model_.get(); }

  void OpenAboutMemory(chrome::HostDesktopType desktop_type);

 private:
  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Basic);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, Resources);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Init);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest, Sort);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
                           SelectionAdaptsToSorting);

  // Obtain an instance via GetInstance().
  TaskManager();
  friend struct DefaultSingletonTraits<TaskManager>;

  ~TaskManager();

  // The model used for gathering and processing task data. It is ref counted
  // because it is passed as a parameter to MessageLoop::InvokeLater().
  scoped_refptr<TaskManagerModel> model_;

  DISALLOW_COPY_AND_ASSIGN(TaskManager);
};

class TaskManagerModelObserver {
 public:
  virtual ~TaskManagerModelObserver() {}

  // Invoked when the model has been completely changed.
  virtual void OnModelChanged() = 0;

  // Invoked when a range of items has changed.
  virtual void OnItemsChanged(int start, int length) = 0;

  // Invoked when new items are added.
  virtual void OnItemsAdded(int start, int length) = 0;

  // Invoked when a range of items has been removed.
  virtual void OnItemsRemoved(int start, int length) = 0;

  // Invoked when a range of items is to be immediately removed. It differs
  // from OnItemsRemoved by the fact that the item is still in the task manager,
  // so it can be queried for and found.
  virtual void OnItemsToBeRemoved(int start, int length) {}

  // Invoked when the initialization of the model has been finished and
  // periodical updates is started. The first periodical update will be done
  // in a few seconds. (depending on platform)
  virtual void OnReadyPeriodicalUpdate() {}
};

// The model used by TaskManager.
//
// TaskManagerModel caches the values from all task_manager::Resources. This is
// done so the UI sees a consistant view of the resources until it is told a
// value has been updated.
class TaskManagerModel : public base::RefCountedThreadSafe<TaskManagerModel> {
 public:
  // (start, length)
  typedef std::pair<int, int> GroupRange;

  explicit TaskManagerModel(TaskManager* task_manager);

  void AddObserver(TaskManagerModelObserver* observer);
  void RemoveObserver(TaskManagerModelObserver* observer);

  // Returns number of registered resources.
  int ResourceCount() const;
  // Returns number of registered groups.
  int GroupCount() const;

  // Methods to return raw resource information.
  int64 GetNetworkUsage(int index) const;
  double GetCPUUsage(int index) const;
  base::ProcessId GetProcessId(int index) const;
  base::ProcessHandle GetProcess(int index) const;
  int GetResourceUniqueId(int index) const;
  // Returns the index of resource that has the given |unique_id|. Returns -1 if
  // no resouce has the |unique_id|.
  int GetResourceIndexByUniqueId(const int unique_id) const;

  // Catchall method that calls off to the appropriate GetResourceXXX method
  // based on |col_id|. |col_id| is an IDS_ value used to identify the column.
  string16 GetResourceById(int index, int col_id) const;

  // Methods to return formatted resource information.
  const string16& GetResourceTitle(int index) const;
  const string16& GetResourceProfileName(int index) const;
  string16 GetResourceNetworkUsage(int index) const;
  string16 GetResourceCPUUsage(int index) const;
  string16 GetResourcePrivateMemory(int index) const;
  string16 GetResourceSharedMemory(int index) const;
  string16 GetResourcePhysicalMemory(int index) const;
  string16 GetResourceProcessId(int index) const;
  string16 GetResourceGDIHandles(int index) const;
  string16 GetResourceUSERHandles(int index) const;
  string16 GetResourceWebCoreImageCacheSize(int index) const;
  string16 GetResourceWebCoreScriptsCacheSize(int index) const;
  string16 GetResourceWebCoreCSSCacheSize(int index) const;
  string16 GetResourceVideoMemory(int index) const;
  string16 GetResourceFPS(int index) const;
  string16 GetResourceSqliteMemoryUsed(int index) const;
  string16 GetResourceGoatsTeleported(int index) const;
  string16 GetResourceV8MemoryAllocatedSize(int index) const;

  // Gets the private memory (in bytes) that should be displayed for the passed
  // resource index. Caches the result since this calculation can take time on
  // some platforms.
  bool GetPrivateMemory(int index, size_t* result) const;

  // Gets the shared memory (in bytes) that should be displayed for the passed
  // resource index. Caches the result since this calculation can take time on
  // some platforms.
  bool GetSharedMemory(int index, size_t* result) const;

  // Gets the physical memory (in bytes) that should be displayed for the passed
  // resource index.
  bool GetPhysicalMemory(int index, size_t* result) const;

  // On Windows, get the current and peak number of GDI handles in use.
  void GetGDIHandles(int index, size_t* current, size_t* peak) const;

  // On Windows, get the current and peak number of USER handles in use.
  void GetUSERHandles(int index, size_t* current, size_t* peak) const;

  // Gets the statuses of webkit. Return false if the resource for the given row
  // isn't a renderer.
  bool GetWebCoreCacheStats(int index,
                            WebKit::WebCache::ResourceTypeStats* result) const;

  // Gets the GPU memory allocated of the given page.
  bool GetVideoMemory(int index,
                      size_t* video_memory,
                      bool* has_duplicates) const;

  // Gets the fps of the given page. Return false if the resource for the given
  // row isn't a renderer.
  bool GetFPS(int index, float* result) const;

  // Gets the sqlite memory (in byte). Return false if the resource for the
  // given row doesn't report information.
  bool GetSqliteMemoryUsedBytes(int index, size_t* result) const;

  // Gets the amount of memory allocated for javascript. Returns false if the
  // resource for the given row isn't a renderer.
  bool GetV8Memory(int index, size_t* result) const;

  // Gets the amount of memory used for javascript. Returns false if the
  // resource for the given row isn't a renderer.
  bool GetV8MemoryUsed(int index, size_t* result) const;

  // Returns true if resource for the given row can be activated.
  bool CanActivate(int index) const;

  // Returns true if resource for the given row can be inspected using developer
  // tools.
  bool CanInspect(int index) const;

  // Invokes or reveals developer tools window for resource in the given row.
  void Inspect(int index) const;

  // See design doc at http://go/at-teleporter for more information.
  int GetGoatsTeleported(int index) const;

  // Returns true if the resource is first/last in its group (resources
  // rendered by the same process are groupped together).
  bool IsResourceFirstInGroup(int index) const;
  bool IsResourceLastInGroup(int index) const;

  // Returns true if the resource runs in the background (not visible to the
  // user, e.g. extension background pages and BackgroundContents).
  bool IsBackgroundResource(int index) const;

  // Returns icon to be used for resource (for example a favicon).
  gfx::ImageSkia GetResourceIcon(int index) const;

  // Returns the group range of resource.
  GroupRange GetGroupRangeForResource(int index) const;

  // Returns an index of groups to which the resource belongs.
  int GetGroupIndexForResource(int index) const;

  // Returns an index of resource which belongs to the |group_index|th group
  // and which is the |index_in_group|th resource in group.
  int GetResourceIndexForGroup(int group_index, int index_in_group) const;

  // Compares values in column |col_id| and rows |row1|, |row2|.
  // Returns -1 if value in |row1| is less than value in |row2|,
  // 0 if they are equal, and 1 otherwise.
  int CompareValues(int row1, int row2, int col_id) const;

  // Returns the unique child process ID generated by Chromium, not the OS
  // process id. This is used to identify processes internally and for
  // extensions. It is not meant to be displayed to the user.
  int GetUniqueChildProcessId(int index) const;

  // Returns the type of the given resource.
  task_manager::Resource::Type GetResourceType(int index) const;

  // Returns WebContents of given resource or NULL if not applicable.
  content::WebContents* GetResourceWebContents(int index) const;

  // Returns Extension of given resource or NULL if not applicable.
  const extensions::Extension* GetResourceExtension(int index) const;

  void AddResource(task_manager::Resource* resource);
  void RemoveResource(task_manager::Resource* resource);

  void StartUpdating();
  void StopUpdating();

  // Listening involves calling StartUpdating on all resource providers. This
  // causes all of them to subscribe to notifications and enumerate current
  // resources. It differs from StartUpdating that it doesn't start the
  // Refresh timer. The end result is that we have a full view of resources, but
  // don't spend unneeded time updating, unless we have a real need to.
  void StartListening();
  void StopListening();

  void Clear();  // Removes all items.

  // Sends OnModelChanged() to all observers to inform them of significant
  // changes to the model.
  void ModelChanged();

   // Updates the values for all rows.
  void Refresh();

  void NotifyResourceTypeStats(
        base::ProcessId renderer_id,
        const WebKit::WebCache::ResourceTypeStats& stats);

  void NotifyFPS(base::ProcessId renderer_id,
                 int routing_id,
                 float fps);

  void NotifyVideoMemoryUsageStats(
      const content::GPUVideoMemoryUsageStats& video_memory_usage_stats);

  void NotifyV8HeapStats(base::ProcessId renderer_id,
                         size_t v8_memory_allocated,
                         size_t v8_memory_used);

  void NotifyBytesRead(const net::URLRequest& request, int bytes_read);

  void RegisterOnDataReadyCallback(const base::Closure& callback);

  void NotifyDataReady();

 private:
  friend class base::RefCountedThreadSafe<TaskManagerModel>;
  friend class TaskManagerBrowserTest;
  FRIEND_TEST_ALL_PREFIXES(ExtensionApiTest, ProcessesVsTaskManager);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerTest, RefreshCalled);
  FRIEND_TEST_ALL_PREFIXES(TaskManagerWindowControllerTest,
                           SelectionAdaptsToSorting);

  enum UpdateState {
    IDLE = 0,      // Currently not updating.
    TASK_PENDING,  // An update task is pending.
    STOPPING       // A update task is pending and it should stop the update.
  };

  // The delay between updates of the information (in ms).
#if defined(OS_MACOSX)
  // Match Activity Monitor's default refresh rate.
  static const int kUpdateTimeMs = 2000;
#else
  static const int kUpdateTimeMs = 1000;
#endif

  // Values cached per resource. Values are validated on demand. The is_XXX
  // members indicate if a value is valid.
  struct PerResourceValues {
    PerResourceValues();
    ~PerResourceValues();

    bool is_title_valid;
    string16 title;

    bool is_profile_name_valid;
    string16 profile_name;

    // No is_network_usage since default (0) is fine.
    int64 network_usage;

    bool is_process_id_valid;
    base::ProcessId process_id;

    bool is_goats_teleported_valid;
    int goats_teleported;

    bool is_webcore_stats_valid;
    WebKit::WebCache::ResourceTypeStats webcore_stats;

    bool is_fps_valid;
    float fps;

    bool is_sqlite_memory_bytes_valid;
    size_t sqlite_memory_bytes;

    bool is_v8_memory_valid;
    size_t v8_memory_allocated;
    size_t v8_memory_used;
  };

  // Values cached per process. Values are validated on demand. The is_XXX
  // members indicate if a value is valid.
  struct PerProcessValues {
    PerProcessValues();
    ~PerProcessValues();

    bool is_cpu_usage_valid;
    double cpu_usage;

    bool is_private_and_shared_valid;
    size_t private_bytes;
    size_t shared_bytes;

    bool is_physical_memory_valid;
    size_t physical_memory;

    bool is_video_memory_valid;
    size_t video_memory;
    bool video_memory_has_duplicates;

    bool is_gdi_handles_valid;
    size_t gdi_handles;
    size_t gdi_handles_peak;

    bool is_user_handles_valid;
    size_t user_handles;
    size_t user_handles_peak;
  };

  typedef std::vector<task_manager::Resource*> ResourceList;
  typedef std::vector<scoped_refptr<task_manager::ResourceProvider> >
      ResourceProviderList;
  typedef std::map<base::ProcessHandle, ResourceList*> GroupMap;
  typedef std::map<base::ProcessHandle, base::ProcessMetrics*> MetricsMap;
  typedef std::map<task_manager::Resource*, int64> ResourceValueMap;
  typedef std::map<task_manager::Resource*,
                   PerResourceValues> PerResourceCache;
  typedef std::map<base::ProcessHandle, PerProcessValues> PerProcessCache;

  // This struct is used to exchange information between the io and ui threads.
  struct BytesReadParam {
    BytesReadParam(int origin_pid,
                   int render_process_host_child_id,
                   int routing_id,
                   int byte_count)
        : origin_pid(origin_pid),
          render_process_host_child_id(render_process_host_child_id),
          routing_id(routing_id),
          byte_count(byte_count) {}

    // The process ID that triggered the request.  For plugin requests this
    // will differ from the renderer process ID.
    int origin_pid;

    // The child ID of the RenderProcessHost this request was routed through.
    int render_process_host_child_id;

    int routing_id;
    int byte_count;
  };

  ~TaskManagerModel();

  // Callback from the timer to refresh. Invokes Refresh() as appropriate.
  void RefreshCallback();

  void RefreshVideoMemoryUsageStats();

  // Returns the network usage (in bytes per seconds) for the specified
  // resource. That's the value retrieved at the last timer's tick.
  int64 GetNetworkUsageForResource(task_manager::Resource* resource) const;

  // Called on the UI thread when some bytes are read.
  void BytesRead(BytesReadParam param);

  void MultipleBytesRead(const std::vector<BytesReadParam>* params);

  // Notifies the UI thread about all the bytes read. Allows for coalescing
  // multiple bytes read into a single task for the UI thread. This is important
  // for when downloading a lot of data on the IO thread, since posting a Task
  // for each one is expensive.
  void NotifyMultipleBytesRead();

  // Returns the network usage (in byte per second) that should be displayed for
  // the passed |resource|.  -1 means the information is not available for that
  // resource.
  int64 GetNetworkUsage(task_manager::Resource* resource) const;

  // Returns the CPU usage (in %) that should be displayed for the passed
  // |resource|.
  double GetCPUUsage(task_manager::Resource* resource) const;

  // Given a number, this function returns the formatted string that should be
  // displayed in the task manager's memory cell.
  string16 GetMemCellText(int64 number) const;

  // Verifies the private and shared memory for |handle| is valid in
  // |per_process_cache_|. Returns true if the data in |per_process_cache_| is
  // valid.
  bool CachePrivateAndSharedMemory(base::ProcessHandle handle) const;

  // Verifies |webcore_stats| in |per_resource_cache_|, returning true on
  // success.
  bool CacheWebCoreStats(int index) const;

  // Verifies |v8_memory_allocated| and |v8_memory_used| in
  // |per_resource_cache_|. Returns true if valid, false if not valid.
  bool CacheV8Memory(int index) const;

  // Adds a resource provider to be managed.
  void AddResourceProvider(task_manager::ResourceProvider* provider);

  // Returns the PerResourceValues for the specified index.
  PerResourceValues& GetPerResourceValues(int index) const;

  // Returns the Resource for the specified index.
  task_manager::Resource* GetResource(int index) const;

  // The list of providers to the task manager. They are ref counted.
  ResourceProviderList providers_;

  // The list of all the resources displayed in the task manager. They are owned
  // by the ResourceProviders.
  ResourceList resources_;

  // A map to keep tracks of the grouped resources (they are grouped if they
  // share the same process). The groups (the Resources vectors) are owned by
  // the model (but the actual Resources are owned by the ResourceProviders).
  GroupMap group_map_;

  // A map to retrieve the process metrics for a process. The ProcessMetrics are
  // owned by the model.
  MetricsMap metrics_map_;

  // A map that keeps track of the number of bytes read per process since last
  // tick. The Resources are owned by the ResourceProviders.
  ResourceValueMap current_byte_count_map_;

  // A map that contains the video memory usage for a process
  content::GPUVideoMemoryUsageStats video_memory_usage_stats_;

  // Set to true when we've requested video stats and false once we get them.
  bool pending_video_memory_usage_stats_update_;

  // An observer waiting for video memory usage stats updates from the GPU
  // process
  scoped_ptr<TaskManagerModelGpuDataManagerObserver>
      video_memory_usage_stats_observer_;

  ObserverList<TaskManagerModelObserver> observer_list_;

  // How many calls to StartUpdating have been made without matching calls to
  // StopUpdating.
  int update_requests_;

  // How many calls to StartListening have been made without matching calls to
  // StopListening.
  int listen_requests_;

  // Whether we are currently in the process of updating.
  UpdateState update_state_;

  // A salt lick for the goats.
  uint64 goat_salt_;

  // Resource identifier that is unique within single session.
  int last_unique_id_;

  // Buffer for coalescing BytesReadParam so we don't have to post a task on
  // each NotifyBytesRead() call.
  std::vector<BytesReadParam> bytes_read_buffer_;

  std::vector<base::Closure> on_data_ready_callbacks_;

  // All per-Resource values are stored here.
  mutable PerResourceCache per_resource_cache_;

  // All per-Process values are stored here.
  mutable PerProcessCache per_process_cache_;

  DISALLOW_COPY_AND_ASSIGN(TaskManagerModel);
};

#endif  // CHROME_BROWSER_TASK_MANAGER_TASK_MANAGER_H_
