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

#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/notifications/balloon.h"
#include "chrome/browser/notifications/balloon_collection_impl.h"
#include "chrome/browser/notifications/notification.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/renderer_preferences_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/bindings_policy.h"
#include "content/public/common/renderer_preferences.h"
#include "extensions/browser/view_type_utils.h"
#include "ipc/ipc_message.h"

using content::SiteInstance;
using content::WebContents;

BalloonHost::BalloonHost(Balloon* balloon)
    : balloon_(balloon),
      initialized_(false),
      should_notify_on_disconnect_(false),
      enable_web_ui_(false),
      extension_function_dispatcher_(balloon_->profile(), this) {
  site_instance_ = SiteInstance::CreateForURL(
      balloon_->profile(), balloon_->notification().content_url());
}

void BalloonHost::Shutdown() {
  NotifyDisconnect();
  web_contents_.reset();
  site_instance_ = NULL;
  balloon_ = NULL;  // No longer safe to access |balloon_|
}

extensions::WindowController*
BalloonHost::GetExtensionWindowController() const {
  // Notifications don't have a window controller.
  return NULL;
}

content::WebContents* BalloonHost::GetAssociatedWebContents() const {
  return NULL;
}

const string16& BalloonHost::GetSource() const {
  return balloon_->notification().display_source();
}

void BalloonHost::CloseContents(WebContents* source) {
  if (!balloon_)
    return;
  balloon_->CloseByScript();
  NotifyDisconnect();
}

void BalloonHost::HandleMouseDown() {
  if (balloon_)
    balloon_->OnClick();
}

void BalloonHost::ResizeDueToAutoResize(WebContents* source,
                                        const gfx::Size& pref_size) {
  if (balloon_)
    balloon_->ResizeDueToAutoResize(pref_size);
}

void BalloonHost::AddNewContents(WebContents* source,
                                 WebContents* new_contents,
                                 WindowOpenDisposition disposition,
                                 const gfx::Rect& initial_pos,
                                 bool user_gesture,
                                 bool* was_blocked) {
  Browser* browser = chrome::FindLastActiveWithProfile(
      Profile::FromBrowserContext(new_contents->GetBrowserContext()),
      chrome::GetActiveDesktop());
  if (browser) {
    chrome::AddWebContents(browser, NULL, new_contents, disposition,
                           initial_pos, user_gesture, was_blocked);
  }
}

void BalloonHost::RenderViewCreated(content::RenderViewHost* render_view_host) {
  gfx::Size min_size(BalloonCollectionImpl::min_balloon_width(),
                     BalloonCollectionImpl::min_balloon_height());
  gfx::Size max_size(BalloonCollectionImpl::max_balloon_width(),
                     BalloonCollectionImpl::max_balloon_height());
  render_view_host->EnableAutoResize(min_size, max_size);

  if (enable_web_ui_)
    render_view_host->AllowBindings(content::BINDINGS_POLICY_WEB_UI);
}

void BalloonHost::RenderViewReady() {
  should_notify_on_disconnect_ = true;
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_NOTIFY_BALLOON_CONNECTED,
      content::Source<BalloonHost>(this),
      content::NotificationService::NoDetails());
}

void BalloonHost::RenderProcessGone(base::TerminationStatus status) {
  CloseContents(web_contents_.get());
}

bool BalloonHost::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(BalloonHost, message)
    IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void BalloonHost::OnRequest(const ExtensionHostMsg_Request_Params& params) {
  extension_function_dispatcher_.Dispatch(params,
                                          web_contents_->GetRenderViewHost());
}

void BalloonHost::Init() {
  DCHECK(!web_contents_.get()) << "BalloonViewHost already initialized.";
  web_contents_.reset(WebContents::Create(
      WebContents::CreateParams(balloon_->profile(), site_instance_.get())));
  extensions::SetViewType(
      web_contents_.get(), extensions::VIEW_TYPE_NOTIFICATION);
  web_contents_->SetDelegate(this);
  Observe(web_contents_.get());
  renderer_preferences_util::UpdateFromSystemSettings(
      web_contents_->GetMutableRendererPrefs(), balloon_->profile());
  web_contents_->GetRenderViewHost()->SyncRendererPrefs();

  web_contents_->GetController().LoadURL(
      balloon_->notification().content_url(), content::Referrer(),
      content::PAGE_TRANSITION_LINK, std::string());

  initialized_ = true;
}

void BalloonHost::EnableWebUI() {
  DCHECK(!web_contents_.get()) <<
      "EnableWebUI has to be called before a renderer is created.";
  enable_web_ui_ = true;
}

BalloonHost::~BalloonHost() {
}

void BalloonHost::NotifyDisconnect() {
  if (!should_notify_on_disconnect_)
    return;

  should_notify_on_disconnect_ = false;
  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_NOTIFY_BALLOON_DISCONNECTED,
      content::Source<BalloonHost>(this),
      content::NotificationService::NoDetails());
}

bool BalloonHost::IsRenderViewReady() const {
  return should_notify_on_disconnect_;
}

bool BalloonHost::CanLoadDataURLsInWebUI() const {
#if defined(OS_CHROMEOS)
  // Chrome OS uses data URLs in WebUI BalloonHosts.  We normally do not allow
  // data URLs in WebUI renderers, but normal pages cannot target BalloonHosts,
  // so this should be safe.
  return true;
#else
  return false;
#endif
}
