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

#include "base/strings/string16.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/notifications/balloon_host.h"
#include "chrome/browser/notifications/balloon_notification_ui_manager.h"
#include "chrome/browser/task_manager/task_manager.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia.h"

namespace task_manager {

class NotificationResource : public Resource {
 public:
  explicit NotificationResource(BalloonHost* balloon_host);
  virtual ~NotificationResource();

  // Resource interface
  virtual base::string16 GetTitle() const OVERRIDE;
  virtual base::string16 GetProfileName() const OVERRIDE;
  virtual gfx::ImageSkia GetIcon() const OVERRIDE;
  virtual base::ProcessHandle GetProcess() const OVERRIDE;
  virtual int GetUniqueChildProcessId() const OVERRIDE;
  virtual Type GetType() const OVERRIDE;
  virtual bool CanInspect() const OVERRIDE;
  virtual void Inspect() const OVERRIDE;
  virtual bool SupportNetworkUsage() const OVERRIDE;
  virtual void SetSupportNetworkUsage() OVERRIDE { }

 private:
  // The icon painted for notifications.       .
  static gfx::ImageSkia* default_icon_;

  // Non-owned pointer to the balloon host.
  BalloonHost* balloon_host_;

  // Cached data about the balloon host.
  base::ProcessHandle process_handle_;
  int pid_;
  int unique_process_id_;
  base::string16 title_;

  DISALLOW_COPY_AND_ASSIGN(NotificationResource);
};

gfx::ImageSkia* NotificationResource::default_icon_ = NULL;

NotificationResource::NotificationResource(BalloonHost* balloon_host)
    : balloon_host_(balloon_host) {
  if (!default_icon_) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    default_icon_ = rb.GetImageSkiaNamed(IDR_PLUGINS_FAVICON);
  }
  process_handle_ =
      balloon_host_->web_contents()->GetRenderProcessHost()->GetHandle();
  unique_process_id_ =
      balloon_host_->web_contents()->GetRenderProcessHost()->GetID();
  pid_ = base::GetProcId(process_handle_);
  title_ = l10n_util::GetStringFUTF16(IDS_TASK_MANAGER_NOTIFICATION_PREFIX,
                                      balloon_host_->GetSource());
}

NotificationResource::~NotificationResource() {
}

base::string16 NotificationResource::GetTitle() const {
  return title_;
}

base::string16 NotificationResource::GetProfileName() const {
  return base::string16();
}

gfx::ImageSkia NotificationResource::GetIcon() const {
  return *default_icon_;
}

base::ProcessHandle NotificationResource::GetProcess() const {
  return process_handle_;
}

int NotificationResource::GetUniqueChildProcessId() const {
  return unique_process_id_;
}

Resource::Type NotificationResource::GetType() const {
  return NOTIFICATION;
}

bool NotificationResource::CanInspect() const {
  return true;
}

void NotificationResource::Inspect() const {
  DevToolsWindow::OpenDevToolsWindow(
      balloon_host_->web_contents()->GetRenderViewHost());
}

bool NotificationResource::SupportNetworkUsage() const {
  return false;
}

////////////////////////////////////////////////////////////////////////////////
// NotificationResourceProvider class
////////////////////////////////////////////////////////////////////////////////

// static
NotificationResourceProvider*
NotificationResourceProvider::Create(TaskManager* task_manager) {
  return new NotificationResourceProvider(task_manager);
}

NotificationResourceProvider::
    NotificationResourceProvider(TaskManager* task_manager)
    : task_manager_(task_manager),
      updating_(false) {
}

NotificationResourceProvider::~NotificationResourceProvider() {
}

Resource* NotificationResourceProvider::GetResource(
    int origin_pid,
    int render_process_host_id,
    int routing_id) {
  // TODO(johnnyg): provide resources by pid if necessary.
  return NULL;
}

void NotificationResourceProvider::StartUpdating() {
  // MessageCenter does not use Balloons.
  if (NotificationUIManager::DelegatesToMessageCenter())
    return;

  DCHECK(!updating_);
  updating_ = true;

  // Add all the existing BalloonHosts.
  BalloonNotificationUIManager* balloon_manager =
      static_cast<BalloonNotificationUIManager*>(
          g_browser_process->notification_ui_manager());
  BalloonCollection* collection = balloon_manager->balloon_collection();
  const BalloonCollection::Balloons& balloons =
      collection->GetActiveBalloons();
  for (BalloonCollection::Balloons::const_iterator it = balloons.begin();
       it != balloons.end(); ++it) {
    BalloonHost* balloon_host = (*it)->balloon_view()->GetHost();
    if (balloon_host)
      AddToTaskManager(balloon_host);
  }
  // Register for notifications about extension process changes.
  registrar_.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
                 content::NotificationService::AllSources());
  registrar_.Add(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
                 content::NotificationService::AllSources());
}

void NotificationResourceProvider::StopUpdating() {
  // MessageCenter does not use Balloons.
  if (NotificationUIManager::DelegatesToMessageCenter())
    return;

  DCHECK(updating_);
  updating_ = false;

  // Unregister for notifications about extension process changes.
  registrar_.Remove(this, chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
                    content::NotificationService::AllSources());
  registrar_.Remove(this, chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
                    content::NotificationService::AllSources());

  // Delete all the resources.
  STLDeleteContainerPairSecondPointers(resources_.begin(), resources_.end());
  resources_.clear();
}

void NotificationResourceProvider::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED:
      AddToTaskManager(content::Source<BalloonHost>(source).ptr());
      break;
    case chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED:
      RemoveFromTaskManager(content::Source<BalloonHost>(source).ptr());
      break;
    default:
      NOTREACHED() << "Unexpected notification.";
      return;
  }
}

void NotificationResourceProvider::AddToTaskManager(
    BalloonHost* balloon_host) {
  NotificationResource* resource = new NotificationResource(balloon_host);
  DCHECK(resources_.find(balloon_host) == resources_.end());
  resources_[balloon_host] = resource;
  task_manager_->AddResource(resource);
}

void NotificationResourceProvider::RemoveFromTaskManager(
    BalloonHost* balloon_host) {
  if (!updating_)
    return;
  std::map<BalloonHost*, NotificationResource*>::iterator iter =
      resources_.find(balloon_host);
  if (iter == resources_.end())
    return;

  // Remove the resource from the Task Manager.
  NotificationResource* resource = iter->second;
  task_manager_->RemoveResource(resource);

  // Remove it from the map.
  resources_.erase(iter);

  // Finally, delete the resource.
  delete resource;
}

}  // namespace task_manager
