// Copyright 2013 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/ui/fast_unload_controller.h"

#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/tab_contents/core_tab_helper.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"

namespace chrome {


////////////////////////////////////////////////////////////////////////////////
// DetachedWebContentsDelegate will delete web contents when they close.
class FastUnloadController::DetachedWebContentsDelegate
    : public content::WebContentsDelegate {
 public:
  DetachedWebContentsDelegate() { }
  virtual ~DetachedWebContentsDelegate() { }

 private:
  // WebContentsDelegate implementation.
  virtual bool ShouldSuppressDialogs() OVERRIDE {
    return true;  // Return true so dialogs are suppressed.
  }

  virtual void CloseContents(content::WebContents* source) OVERRIDE {
    // Finished detached close.
    // FastUnloadController will observe
    // |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|.
    delete source;
  }

  DISALLOW_COPY_AND_ASSIGN(DetachedWebContentsDelegate);
};

////////////////////////////////////////////////////////////////////////////////
// FastUnloadController, public:

FastUnloadController::FastUnloadController(Browser* browser)
    : browser_(browser),
      tab_needing_before_unload_ack_(NULL),
      is_attempting_to_close_browser_(false),
      detached_delegate_(new DetachedWebContentsDelegate()),
      weak_factory_(this) {
  browser_->tab_strip_model()->AddObserver(this);
}

FastUnloadController::~FastUnloadController() {
  browser_->tab_strip_model()->RemoveObserver(this);
}

bool FastUnloadController::CanCloseContents(content::WebContents* contents) {
  // Don't try to close the tab when the whole browser is being closed, since
  // that avoids the fast shutdown path where we just kill all the renderers.
  return !is_attempting_to_close_browser_ ||
      is_calling_before_unload_handlers();
}

// static
bool FastUnloadController::ShouldRunUnloadEventsHelper(
    content::WebContents* contents) {
  // If |contents| is being inspected, devtools needs to intercept beforeunload
  // events.
  return DevToolsWindow::GetInstanceForInspectedRenderViewHost(
      contents->GetRenderViewHost()) != NULL;
}

// static
bool FastUnloadController::RunUnloadEventsHelper(
    content::WebContents* contents) {
  // If there's a devtools window attached to |contents|,
  // we would like devtools to call its own beforeunload handlers first,
  // and then call beforeunload handlers for |contents|.
  // See DevToolsWindow::InterceptPageBeforeUnload for details.
  if (DevToolsWindow::InterceptPageBeforeUnload(contents)) {
    return true;
  }
  // If the WebContents is not connected yet, then there's no unload
  // handler we can fire even if the WebContents has an unload listener.
  // One case where we hit this is in a tab that has an infinite loop
  // before load.
  if (contents->NeedToFireBeforeUnload()) {
    // If the page has unload listeners, then we tell the renderer to fire
    // them. Once they have fired, we'll get a message back saying whether
    // to proceed closing the page or not, which sends us back to this method
    // with the NeedToFireBeforeUnload bit cleared.
    contents->DispatchBeforeUnload(false);
    return true;
  }
  return false;
}

bool FastUnloadController::BeforeUnloadFired(content::WebContents* contents,
                                             bool proceed) {
  if (!proceed)
    DevToolsWindow::OnPageCloseCanceled(contents);

  if (!is_attempting_to_close_browser_) {
    if (!proceed) {
      contents->SetClosedByUserGesture(false);
    } else {
      // No more dialogs are possible, so remove the tab and finish
      // running unload listeners asynchrounously.
      browser_->tab_strip_model()->delegate()->CreateHistoricalTab(contents);
      DetachWebContents(contents);
    }
    return proceed;
  }

  if (!proceed) {
    CancelWindowClose();
    contents->SetClosedByUserGesture(false);
    return false;
  }

  if (tab_needing_before_unload_ack_ == contents) {
    // Now that beforeunload has fired, queue the tab to fire unload.
    tab_needing_before_unload_ack_ = NULL;
    tabs_needing_unload_.insert(contents);
    ProcessPendingTabs();
    // We want to handle firing the unload event ourselves since we want to
    // fire all the beforeunload events before attempting to fire the unload
    // events should the user cancel closing the browser.
    return false;
  }

  return true;
}

bool FastUnloadController::ShouldCloseWindow() {
  if (HasCompletedUnloadProcessing())
    return true;

  // Special case for when we quit an application. The Devtools window can
  // close if it's beforeunload event has already fired which will happen due
  // to the interception of it's content's beforeunload.
  if (browser_->is_devtools() &&
      DevToolsWindow::HasFiredBeforeUnloadEventForDevToolsBrowser(browser_)) {
    return true;
  }

  // The behavior followed here varies based on the current phase of the
  // operation and whether a batched shutdown is in progress.
  //
  // If there are tabs with outstanding beforeunload handlers:
  // 1. If a batched shutdown is in progress: return false.
  //    This is to prevent interference with batched shutdown already in
  //    progress.
  // 2. Otherwise: start sending beforeunload events and return false.
  //
  // Otherwise, If there are no tabs with outstanding beforeunload handlers:
  // 3. If a batched shutdown is in progress: start sending unload events and
  //    return false.
  // 4. Otherwise: return true.
  is_attempting_to_close_browser_ = true;
  // Cases 1 and 4.
  bool need_beforeunload_fired = TabsNeedBeforeUnloadFired();
  if (need_beforeunload_fired == is_calling_before_unload_handlers())
    return !need_beforeunload_fired;

  // Cases 2 and 3.
  on_close_confirmed_.Reset();
  ProcessPendingTabs();
  return false;
}

bool FastUnloadController::CallBeforeUnloadHandlers(
    const base::Callback<void(bool)>& on_close_confirmed) {
// The devtools browser gets its beforeunload events as the results of
// intercepting events from the inspected tab, so don't send them here as well.
  if (browser_->is_devtools() || !TabsNeedBeforeUnloadFired())
    return false;

  on_close_confirmed_ = on_close_confirmed;
  is_attempting_to_close_browser_ = true;
  ProcessPendingTabs();
  return true;
}

void FastUnloadController::ResetBeforeUnloadHandlers() {
  if (!is_calling_before_unload_handlers())
    return;
  CancelWindowClose();
}

bool FastUnloadController::TabsNeedBeforeUnloadFired() {
  if (!tabs_needing_before_unload_.empty() ||
      tab_needing_before_unload_ack_ != NULL)
    return true;

  if (!is_calling_before_unload_handlers() && !tabs_needing_unload_.empty())
    return false;

  for (int i = 0; i < browser_->tab_strip_model()->count(); ++i) {
    content::WebContents* contents =
        browser_->tab_strip_model()->GetWebContentsAt(i);
    bool should_fire_beforeunload = contents->NeedToFireBeforeUnload() ||
        DevToolsWindow::NeedsToInterceptBeforeUnload(contents);
    if (!ContainsKey(tabs_needing_unload_, contents) &&
        !ContainsKey(tabs_needing_unload_ack_, contents) &&
        tab_needing_before_unload_ack_ != contents &&
        should_fire_beforeunload)
      tabs_needing_before_unload_.insert(contents);
  }
  return !tabs_needing_before_unload_.empty();
}

bool FastUnloadController::HasCompletedUnloadProcessing() const {
  return is_attempting_to_close_browser_ &&
      tabs_needing_before_unload_.empty() &&
      tab_needing_before_unload_ack_ == NULL &&
      tabs_needing_unload_.empty() &&
      tabs_needing_unload_ack_.empty();
}

void FastUnloadController::CancelWindowClose() {
  // Closing of window can be canceled from a beforeunload handler.
  DCHECK(is_attempting_to_close_browser_);
  tabs_needing_before_unload_.clear();
  if (tab_needing_before_unload_ack_ != NULL) {
    CoreTabHelper* core_tab_helper =
        CoreTabHelper::FromWebContents(tab_needing_before_unload_ack_);
    core_tab_helper->OnCloseCanceled();
    DevToolsWindow::OnPageCloseCanceled(tab_needing_before_unload_ack_);
    tab_needing_before_unload_ack_ = NULL;
  }
  for (WebContentsSet::iterator it = tabs_needing_unload_.begin();
       it != tabs_needing_unload_.end(); it++) {
    content::WebContents* contents = *it;

    CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents);
    core_tab_helper->OnCloseCanceled();
    DevToolsWindow::OnPageCloseCanceled(contents);
  }
  tabs_needing_unload_.clear();

  // No need to clear tabs_needing_unload_ack_. Those tabs are already detached.

  if (is_calling_before_unload_handlers()) {
    base::Callback<void(bool)> on_close_confirmed = on_close_confirmed_;
    on_close_confirmed_.Reset();
    on_close_confirmed.Run(false);
  }

  is_attempting_to_close_browser_ = false;

  content::NotificationService::current()->Notify(
      chrome::NOTIFICATION_BROWSER_CLOSE_CANCELLED,
      content::Source<Browser>(browser_),
      content::NotificationService::NoDetails());
}

////////////////////////////////////////////////////////////////////////////////
// FastUnloadController, content::NotificationObserver implementation:

void FastUnloadController::Observe(
      int type,
      const content::NotificationSource& source,
      const content::NotificationDetails& details) {
  switch (type) {
    case content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED: {
      registrar_.Remove(this,
                        content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
                        source);
      content::WebContents* contents =
          content::Source<content::WebContents>(source).ptr();
      ClearUnloadState(contents);
      break;
    }
    default:
      NOTREACHED() << "Got a notification we didn't register for.";
  }
}

////////////////////////////////////////////////////////////////////////////////
// FastUnloadController, TabStripModelObserver implementation:

void FastUnloadController::TabInsertedAt(content::WebContents* contents,
                                         int index,
                                         bool foreground) {
  TabAttachedImpl(contents);
}

void FastUnloadController::TabDetachedAt(content::WebContents* contents,
                                         int index) {
  TabDetachedImpl(contents);
}

void FastUnloadController::TabReplacedAt(TabStripModel* tab_strip_model,
                                         content::WebContents* old_contents,
                                         content::WebContents* new_contents,
                                         int index) {
  TabDetachedImpl(old_contents);
  TabAttachedImpl(new_contents);
}

void FastUnloadController::TabStripEmpty() {
  // Set is_attempting_to_close_browser_ here, so that extensions, etc, do not
  // attempt to add tabs to the browser before it closes.
  is_attempting_to_close_browser_ = true;
}

////////////////////////////////////////////////////////////////////////////////
// FastUnloadController, private:

void FastUnloadController::TabAttachedImpl(content::WebContents* contents) {
  // If the tab crashes in the beforeunload or unload handler, it won't be
  // able to ack. But we know we can close it.
  registrar_.Add(
      this,
      content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
      content::Source<content::WebContents>(contents));
}

void FastUnloadController::TabDetachedImpl(content::WebContents* contents) {
  if (tabs_needing_unload_ack_.find(contents) !=
      tabs_needing_unload_ack_.end()) {
    // Tab needs unload to complete.
    // It will send |NOTIFICATION_WEB_CONTENTS_DISCONNECTED| when done.
    return;
  }

  // If WEB_CONTENTS_DISCONNECTED was received then the notification may have
  // already been unregistered.
  const content::NotificationSource& source =
      content::Source<content::WebContents>(contents);
  if (registrar_.IsRegistered(this,
                              content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
                              source)) {
    registrar_.Remove(this,
                      content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
                      source);
  }

  if (is_attempting_to_close_browser_)
    ClearUnloadState(contents);
}

bool FastUnloadController::DetachWebContents(content::WebContents* contents) {
  int index = browser_->tab_strip_model()->GetIndexOfWebContents(contents);
  if (index != TabStripModel::kNoTab &&
      contents->NeedToFireBeforeUnload()) {
    tabs_needing_unload_ack_.insert(contents);
    browser_->tab_strip_model()->DetachWebContentsAt(index);
    contents->SetDelegate(detached_delegate_.get());
    CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents);
    core_tab_helper->OnUnloadDetachedStarted();
    return true;
  }
  return false;
}

void FastUnloadController::ProcessPendingTabs() {
  if (!is_attempting_to_close_browser_) {
    // Because we might invoke this after a delay it's possible for the value of
    // is_attempting_to_close_browser_ to have changed since we scheduled the
    // task.
    return;
  }

  if (tab_needing_before_unload_ack_ != NULL) {
    // Wait for |BeforeUnloadFired| before proceeding.
    return;
  }

  // Process a beforeunload handler.
  if (!tabs_needing_before_unload_.empty()) {
    WebContentsSet::iterator it = tabs_needing_before_unload_.begin();
    content::WebContents* contents = *it;
    tabs_needing_before_unload_.erase(it);
    // Null check render_view_host here as this gets called on a PostTask and
    // the tab's render_view_host may have been nulled out.
    if (contents->GetRenderViewHost()) {
      tab_needing_before_unload_ack_ = contents;

      CoreTabHelper* core_tab_helper = CoreTabHelper::FromWebContents(contents);
      core_tab_helper->OnCloseStarted();

      // If there's a devtools window attached to |contents|,
      // we would like devtools to call its own beforeunload handlers first,
      // and then call beforeunload handlers for |contents|.
      // See DevToolsWindow::InterceptPageBeforeUnload for details.
      if (!DevToolsWindow::InterceptPageBeforeUnload(contents))
        contents->DispatchBeforeUnload(false);
    } else {
      ProcessPendingTabs();
    }
    return;
  }

  if (is_calling_before_unload_handlers()) {
    on_close_confirmed_.Run(true);
    return;
  }
  // Process all the unload handlers. (The beforeunload handlers have finished.)
  if (!tabs_needing_unload_.empty()) {
    browser_->OnWindowClosing();

    // Run unload handlers detached since no more interaction is possible.
    WebContentsSet::iterator it = tabs_needing_unload_.begin();
    while (it != tabs_needing_unload_.end()) {
      WebContentsSet::iterator current = it++;
      content::WebContents* contents = *current;
      tabs_needing_unload_.erase(current);
      // Null check render_view_host here as this gets called on a PostTask
      // and the tab's render_view_host may have been nulled out.
      if (contents->GetRenderViewHost()) {
        CoreTabHelper* core_tab_helper =
            CoreTabHelper::FromWebContents(contents);
        core_tab_helper->OnUnloadStarted();
        DetachWebContents(contents);
        contents->GetRenderViewHost()->ClosePage();
      }
    }

    // Get the browser hidden.
    if (browser_->tab_strip_model()->empty()) {
      browser_->TabStripEmpty();
    } else {
      browser_->tab_strip_model()->CloseAllTabs();  // tabs not needing unload
    }
    return;
  }

  if (HasCompletedUnloadProcessing()) {
    browser_->OnWindowClosing();

    // Get the browser closed.
    if (browser_->tab_strip_model()->empty()) {
      browser_->TabStripEmpty();
    } else {
      // There may be tabs if the last tab needing beforeunload crashed.
      browser_->tab_strip_model()->CloseAllTabs();
    }
    return;
  }
}

void FastUnloadController::ClearUnloadState(content::WebContents* contents) {
  if (tabs_needing_unload_ack_.erase(contents) > 0) {
    if (HasCompletedUnloadProcessing())
      PostTaskForProcessPendingTabs();
    return;
  }

  if (!is_attempting_to_close_browser_)
    return;

  if (tab_needing_before_unload_ack_ == contents) {
    tab_needing_before_unload_ack_ = NULL;
    PostTaskForProcessPendingTabs();
    return;
  }

  if (tabs_needing_before_unload_.erase(contents) > 0 ||
      tabs_needing_unload_.erase(contents) > 0) {
    if (tab_needing_before_unload_ack_ == NULL)
      PostTaskForProcessPendingTabs();
  }
}

void FastUnloadController::PostTaskForProcessPendingTabs() {
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&FastUnloadController::ProcessPendingTabs,
                 weak_factory_.GetWeakPtr()));
}

}  // namespace chrome
