// 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_CAPTIVE_PORTAL_CAPTIVE_PORTAL_TAB_HELPER_H_
#define CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_TAB_HELPER_H_

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "chrome/browser/captive_portal/captive_portal_service.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "webkit/common/resource_type.h"

class GURL;
class Profile;

namespace content {
  class WebContents;
}

namespace net {
class SSLInfo;
}

class CaptivePortalLoginDetector;
class CaptivePortalTabReloader;

// Along with the classes it owns, responsible for detecting page loads broken
// by a captive portal, triggering captive portal checks on navigation events
// that may indicate a captive portal is present, or has been removed / logged
// in to, and taking any correcting actions.
//
// It acts as a WebContentsObserver for its CaptivePortalLoginDetector and
// CaptivePortalTabReloader.  It filters out non-main-frame resource loads, and
// treats the commit of an error page as a single event, rather than as 3
// (ProvisionalLoadFail, DidStartProvisionalLoad, DidCommit), which simplifies
// the CaptivePortalTabReloader.  It is also needed by CaptivePortalTabReloaders
// to inform the tab's CaptivePortalLoginDetector when the tab is at a captive
// portal's login page.
//
// The TabHelper assumes that a WebContents can only have one RenderViewHost
// with a provisional load at a time, and tracks only that navigation.  This
// assumption can be violated in rare cases, for example, a same-site
// navigation interrupted by a cross-process navigation started from the
// omnibox, may commit before it can be cancelled.  In these cases, this class
// may pass incorrect messages to the TabReloader, which will, at worst, result
// in not opening up a login tab until a second load fails or not automatically
// reloading a tab after logging in.
//
// For the design doc, see:
// https://docs.google.com/document/d/1k-gP2sswzYNvryu9NcgN7q5XrsMlUdlUdoW9WRaEmfM/edit
class CaptivePortalTabHelper
    : public content::WebContentsObserver,
      public content::NotificationObserver,
      public base::NonThreadSafe,
      public content::WebContentsUserData<CaptivePortalTabHelper> {
 public:
  virtual ~CaptivePortalTabHelper();

  // content::WebContentsObserver:
  virtual void RenderViewDeleted(
      content::RenderViewHost* render_view_host) OVERRIDE;

  virtual void DidStartProvisionalLoadForFrame(
      int64 frame_id,
      int64 parent_frame_id,
      bool is_main_frame,
      const GURL& validated_url,
      bool is_error_page,
      bool is_iframe_srcdoc,
      content::RenderViewHost* render_view_host) OVERRIDE;

  virtual void DidCommitProvisionalLoadForFrame(
      int64 frame_id,
      const base::string16& frame_unique_name,
      bool is_main_frame,
      const GURL& url,
      content::PageTransition transition_type,
      content::RenderViewHost* render_view_host) OVERRIDE;

  virtual void DidFailProvisionalLoad(
      int64 frame_id,
      const base::string16& frame_unique_name,
      bool is_main_frame,
      const GURL& validated_url,
      int error_code,
      const base::string16& error_description,
      content::RenderViewHost* render_view_host) OVERRIDE;

  virtual void DidStopLoading(
      content::RenderViewHost* render_view_host) OVERRIDE;

  // content::NotificationObserver:
  virtual void Observe(
      int type,
      const content::NotificationSource& source,
      const content::NotificationDetails& details) OVERRIDE;

  // Called when a certificate interstitial error page is about to be shown.
  void OnSSLCertError(const net::SSLInfo& ssl_info);

  // A "Login Tab" is a tab that was originally at a captive portal login
  // page.  This is set to false when a captive portal is no longer detected.
  bool IsLoginTab() const;

 private:
  friend class CaptivePortalBrowserTest;
  friend class CaptivePortalTabHelperTest;

  friend class content::WebContentsUserData<CaptivePortalTabHelper>;
  explicit CaptivePortalTabHelper(content::WebContents* web_contents);

  // Called by Observe in response to the corresponding event.
  void OnRedirect(int child_id,
                  ResourceType::Type resource_type,
                  const GURL& new_url);

  // Called by Observe in response to the corresponding event.
  void OnCaptivePortalResults(
      captive_portal::CaptivePortalResult previous_result,
      captive_portal::CaptivePortalResult result);

  void OnLoadAborted();

  // Called to indicate a tab is at, or is navigating to, the captive portal
  // login page.
  void SetIsLoginTab();

  // |this| takes ownership of |tab_reloader|.
  void SetTabReloaderForTest(CaptivePortalTabReloader* tab_reloader);

  const content::RenderViewHost* provisional_render_view_host() const {
    return provisional_render_view_host_;
  }

  CaptivePortalTabReloader* GetTabReloaderForTest();

  // Opens a login tab if the profile's active window doesn't have one already.
  void OpenLoginTab();

  Profile* profile_;

  // Neither of these will ever be NULL.
  scoped_ptr<CaptivePortalTabReloader> tab_reloader_;
  scoped_ptr<CaptivePortalLoginDetector> login_detector_;

  content::WebContents* web_contents_;

  // If a provisional load has failed, and the tab is loading an error page, the
  // error code associated with the error page we're loading.
  // net::OK, otherwise.
  int pending_error_code_;

  // The RenderViewHost with a provisional load, if any.  Can either be
  // the currently displayed RenderViewHost or a pending RenderViewHost for
  // cross-process navitations.  NULL when there's currently no provisional
  // load.
  content::RenderViewHost* provisional_render_view_host_;

  content::NotificationRegistrar registrar_;

  DISALLOW_COPY_AND_ASSIGN(CaptivePortalTabHelper);
};

#endif  // CHROME_BROWSER_CAPTIVE_PORTAL_CAPTIVE_PORTAL_TAB_HELPER_H_
