// 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_PRERENDER_PRERENDER_CONTENTS_H_
#define CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_H_

#include <string>
#include <utility>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chrome/browser/prerender/prerender_final_status.h"
#include "chrome/browser/prerender/prerender_origin.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/common/referrer.h"
#include "ui/gfx/size.h"

class Profile;

namespace base {
class ProcessMetrics;
}

namespace content {
class RenderViewHost;
class SessionStorageNamespace;
class WebContents;
}

namespace history {
struct HistoryAddPageArgs;
}

namespace net {
class URLRequestContextGetter;
}

namespace prerender {

class PrerenderHandle;
class PrerenderManager;
class PrerenderResourceThrottle;

class PrerenderContents : public content::NotificationObserver,
                          public content::WebContentsObserver,
                          public base::SupportsWeakPtr<PrerenderContents> {
 public:
  // PrerenderContents::Create uses the currently registered Factory to create
  // the PrerenderContents. Factory is intended for testing.
  class Factory {
   public:
    Factory() {}
    virtual ~Factory() {}

    // Ownership is not transfered through this interface as prerender_manager,
    // prerender_tracker, and profile are stored as weak pointers.
    virtual PrerenderContents* CreatePrerenderContents(
        PrerenderManager* prerender_manager,
        Profile* profile,
        const GURL& url,
        const content::Referrer& referrer,
        Origin origin,
        uint8 experiment_id) = 0;

   private:
    DISALLOW_COPY_AND_ASSIGN(Factory);
  };

  class Observer {
   public:
    // Signals that the prerender has started running.
    virtual void OnPrerenderStart(PrerenderContents* contents) = 0;

    // Signals that the prerender has had its load event.
    virtual void OnPrerenderStopLoading(PrerenderContents* contents);

    // Signals that the prerender has had its 'DOMContentLoaded' event.
    virtual void OnPrerenderDomContentLoaded(PrerenderContents* contents);

    // Signals that the prerender has stopped running. A PrerenderContents with
    // an unset final status will always call OnPrerenderStop before being
    // destroyed.
    virtual void OnPrerenderStop(PrerenderContents* contents) = 0;

    // Signals that this prerender has just become a MatchComplete replacement.
    virtual void OnPrerenderCreatedMatchCompleteReplacement(
        PrerenderContents* contents, PrerenderContents* replacement);

   protected:
    Observer();
    virtual ~Observer() = 0;
  };

  // Indicates how this PrerenderContents relates to MatchComplete. This is to
  // figure out which histograms to use to record the FinalStatus, Match (record
  // all prerenders and control group prerenders) or MatchComplete (record
  // running prerenders only in the way they would have been recorded in the
  // control group).
  enum MatchCompleteStatus {
    // A regular prerender which will be recorded both in Match and
    // MatchComplete.
    MATCH_COMPLETE_DEFAULT,
    // A prerender that used to be a regular prerender, but has since been
    // replaced by a MatchComplete dummy. Therefore, we will record this only
    // for Match, but not for MatchComplete.
    MATCH_COMPLETE_REPLACED,
    // A prerender that is a MatchComplete dummy replacing a regular prerender.
    // In the control group, our prerender never would have been canceled, so
    // we record in MatchComplete but not Match.
    MATCH_COMPLETE_REPLACEMENT,
    // A prerender that is a MatchComplete dummy, early in the process of being
    // created. This prerender should not fail. Record for MatchComplete, but
    // not Match.
    MATCH_COMPLETE_REPLACEMENT_PENDING,
  };

  virtual ~PrerenderContents();

  // All observers of a PrerenderContents are removed after the OnPrerenderStop
  // event is sent, so there is no need to call RemoveObserver() in the normal
  // use case.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // For MatchComplete correctness, create a dummy replacement prerender
  // contents to stand in for this prerender contents that (which we are about
  // to destroy).
  PrerenderContents* CreateMatchCompleteReplacement();

  bool Init();

  static Factory* CreateFactory();

  // Returns a PrerenderContents from the given web_contents, if it's used for
  // prerendering. Otherwise returns NULL. Handles a NULL input for
  // convenience.
  static PrerenderContents* FromWebContents(content::WebContents* web_contents);

  // Start rendering the contents in the prerendered state. If
  // |is_control_group| is true, this will go through some of the mechanics of
  // starting a prerender, without actually creating the RenderView.
  // |creator_child_id| is the id of the child process that caused the prerender
  // to be created, and is needed so that the prerendered URLs can be sent to it
  // so render-initiated navigations will swap in the prerendered page. |size|
  // indicates the rectangular dimensions that the prerendered page should be.
  // |session_storage_namespace| indicates the namespace that the prerendered
  // page should be part of.
  virtual void StartPrerendering(
      int creator_child_id,
      const gfx::Size& size,
      content::SessionStorageNamespace* session_storage_namespace,
      net::URLRequestContextGetter* request_context);

  // Verifies that the prerendering is not using too many resources, and kills
  // it if not.
  void DestroyWhenUsingTooManyResources();

  content::RenderViewHost* GetRenderViewHostMutable();
  const content::RenderViewHost* GetRenderViewHost() const;

  PrerenderManager* prerender_manager() { return prerender_manager_; }

  base::string16 title() const { return title_; }
  int32 page_id() const { return page_id_; }
  const GURL& prerender_url() const { return prerender_url_; }
  const content::Referrer& referrer() const { return referrer_; }
  bool has_stopped_loading() const { return has_stopped_loading_; }
  bool has_finished_loading() const { return has_finished_loading_; }
  bool prerendering_has_started() const { return prerendering_has_started_; }
  MatchCompleteStatus match_complete_status() const {
    return match_complete_status_;
  }
  void set_match_complete_status(MatchCompleteStatus status) {
    match_complete_status_ = status;
  }

  // Sets the parameter to the value of the associated RenderViewHost's child id
  // and returns a boolean indicating the validity of that id.
  virtual bool GetChildId(int* child_id) const;

  // Sets the parameter to the value of the associated RenderViewHost's route id
  // and returns a boolean indicating the validity of that id.
  virtual bool GetRouteId(int* route_id) const;

  FinalStatus final_status() const { return final_status_; }

  Origin origin() const { return origin_; }
  uint8 experiment_id() const { return experiment_id_; }
  int child_id() const { return child_id_; }

  base::TimeTicks load_start_time() const { return load_start_time_; }

  // Indicates whether this prerendered page can be used for the provided
  // |url| and |session_storage_namespace|.
  bool Matches(
      const GURL& url,
      const content::SessionStorageNamespace* session_storage_namespace) const;

  // content::WebContentsObserver implementation.
  virtual void RenderFrameCreated(
      content::RenderFrameHost* render_frame_host) OVERRIDE;
  virtual void DidStopLoading(
      content::RenderViewHost* render_view_host) OVERRIDE;
  virtual void DocumentLoadedInFrame(
      int64 frame_id, 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 DidFinishLoad(
      int64 frame_id,
      const GURL& validated_url,
      bool is_main_frame,
      content::RenderViewHost* render_view_host) OVERRIDE;
  virtual void DidNavigateMainFrame(
      const content::LoadCommittedDetails& details,
      const content::FrameNavigateParams& params) OVERRIDE;
  virtual void DidGetRedirectForResourceRequest(
      content::RenderViewHost* render_view_host,
      const content::ResourceRedirectDetails& details) OVERRIDE;
  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;

  virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;

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

  // Checks that a URL may be prerendered, for one of the many redirections. If
  // the URL can not be prerendered - for example, it's an ftp URL - |this| will
  // be destroyed and false is returned. Otherwise, true is returned.
  virtual bool CheckURL(const GURL& url);

  // Adds an alias URL. If the URL can not be prerendered, |this| will be
  // destroyed and false is returned.
  bool AddAliasURL(const GURL& url);

  // The prerender WebContents (may be NULL).
  content::WebContents* prerender_contents() const {
    return prerender_contents_.get();
  }

  content::WebContents* ReleasePrerenderContents();

  // Sets the final status, calls OnDestroy and adds |this| to the
  // PrerenderManager's pending deletes list.
  void Destroy(FinalStatus reason);

  // Called by the history tab helper with the information that it woudl have
  // added to the history service had this web contents not been used for
  // prerendering.
  void DidNavigate(const history::HistoryAddPageArgs& add_page_args);

  // Applies all the URL history encountered during prerendering to the
  // new tab.
  void CommitHistory(content::WebContents* tab);

  base::Value* GetAsValue() const;

  // Returns whether a pending cross-site navigation is happening.
  // This could happen with renderer-issued navigations, such as a
  // MouseEvent being dispatched by a link to a website installed as an app.
  bool IsCrossSiteNavigationPending() const;

  // Marks prerender as used and releases any throttled resource requests.
  void PrepareForUse();

  content::SessionStorageNamespace* GetSessionStorageNamespace() const;

  // Cookie events
  enum CookieEvent {
    COOKIE_EVENT_SEND = 0,
    COOKIE_EVENT_CHANGE = 1,
    COOKIE_EVENT_MAX
  };

  // Record a cookie transaction for this prerender contents.
  // In the event of cookies being sent, |earliest_create_date| contains
  // the time that the earliest of the cookies sent was created.
  void RecordCookieEvent(CookieEvent event,
                         bool is_main_frame_http_request,
                         bool is_third_party_cookie,
                         bool is_for_blocking_resource,
                         base::Time earliest_create_date);

  static const int kNumCookieStatuses;
  static const int kNumCookieSendTypes;

  // Called when a PrerenderResourceThrottle defers a request. If the prerender
  // is used it'll be resumed on the IO thread, otherwise they will get
  // cancelled automatically if prerendering is cancelled.
  void AddResourceThrottle(
      const base::WeakPtr<PrerenderResourceThrottle>& throttle);

  // Increments the number of bytes fetched over the network for this prerender.
  void AddNetworkBytes(int64 bytes);

 protected:
  PrerenderContents(PrerenderManager* prerender_manager,
                    Profile* profile,
                    const GURL& url,
                    const content::Referrer& referrer,
                    Origin origin,
                    uint8 experiment_id);

  // Set the final status for how the PrerenderContents was used. This
  // should only be called once, and should be called before the prerender
  // contents are destroyed.
  void SetFinalStatus(FinalStatus final_status);

  // These call out to methods on our Observers, using our observer_list_. Note
  // that NotifyPrerenderStop() also clears the observer list.
  void NotifyPrerenderStart();
  void NotifyPrerenderStopLoading();
  void NotifyPrerenderDomContentLoaded();
  void NotifyPrerenderStop();
  void NotifyPrerenderCreatedMatchCompleteReplacement(
      PrerenderContents* replacement);

  // Called whenever a RenderViewHost is created for prerendering.  Only called
  // once the RenderViewHost has a RenderView and RenderWidgetHostView.
  virtual void OnRenderViewHostCreated(
      content::RenderViewHost* new_render_view_host);

  content::NotificationRegistrar& notification_registrar() {
    return notification_registrar_;
  }

  bool prerendering_has_been_cancelled() const {
    return prerendering_has_been_cancelled_;
  }

  content::WebContents* CreateWebContents(
      content::SessionStorageNamespace* session_storage_namespace);

  bool prerendering_has_started_;

  // Time at which we started to load the URL.  This is used to compute
  // the time elapsed from initiating a prerender until the time the
  // (potentially only partially) prerendered page is shown to the user.
  base::TimeTicks load_start_time_;

  // The prerendered WebContents; may be null.
  scoped_ptr<content::WebContents> prerender_contents_;

  // The session storage namespace id for use in matching. We must save it
  // rather than get it from the RenderViewHost since in the control group
  // we won't have a RenderViewHost.
  int64 session_storage_namespace_id_;

  // The time at which we started prerendering, for the purpose of comparing
  // cookie creation times.
  base::Time start_time_;

 private:
  class WebContentsDelegateImpl;

  // Needs to be able to call the constructor.
  friend class PrerenderContentsFactoryImpl;

  // Returns the ProcessMetrics for the render process, if it exists.
  base::ProcessMetrics* MaybeGetProcessMetrics();

  // Message handlers.
  void OnCancelPrerenderForPrinting();

  ObserverList<Observer> observer_list_;

  // The prerender manager owning this object.
  PrerenderManager* prerender_manager_;

  // The URL being prerendered.
  GURL prerender_url_;

  // The referrer.
  content::Referrer referrer_;

  // The profile being used
  Profile* profile_;

  // Information about the title and URL of the page that this class as a
  // RenderViewHostDelegate has received from the RenderView.
  // Used to apply to the new RenderViewHost delegate that might eventually
  // own the contained RenderViewHost when the prerendered page is shown
  // in a WebContents.
  base::string16 title_;
  int32 page_id_;
  GURL url_;
  content::NotificationRegistrar notification_registrar_;

  // A vector of URLs that this prerendered page matches against.
  // This array can contain more than element as a result of redirects,
  // such as HTTP redirects or javascript redirects.
  std::vector<GURL> alias_urls_;

  bool has_stopped_loading_;

  // True when the main frame has finished loading.
  bool has_finished_loading_;

  // This must be the same value as the PrerenderTracker has recorded for
  // |this|, when |this| has a RenderView.
  FinalStatus final_status_;

  // The MatchComplete status of the prerender, indicating how it relates
  // to being a MatchComplete dummy (see definition of MatchCompleteStatus
  // above).
  MatchCompleteStatus match_complete_status_;

  // Tracks whether or not prerendering has been cancelled by calling Destroy.
  // Used solely to prevent double deletion.
  bool prerendering_has_been_cancelled_;

  // Process Metrics of the render process associated with the
  // RenderViewHost for this object.
  scoped_ptr<base::ProcessMetrics> process_metrics_;

  scoped_ptr<WebContentsDelegateImpl> web_contents_delegate_;

  // These are -1 before a RenderView is created.
  int child_id_;
  int route_id_;

  // Origin for this prerender.
  Origin origin_;

  // Experiment during which this prerender is performed.
  uint8 experiment_id_;

  // The process that created the child id.
  int creator_child_id_;

  // Main frame ID of last committed page.
  int64 main_frame_id_;

  // The size of the WebView from the launching page.
  gfx::Size size_;

  typedef std::vector<history::HistoryAddPageArgs> AddPageVector;

  // Caches pages to be added to the history.
  AddPageVector add_page_vector_;

  // The alias session storage namespace for this prerender.
  scoped_refptr<content::SessionStorageNamespace>
      alias_session_storage_namespace;

  // Indicates what internal cookie events (see prerender_contents.cc) have
  // occurred, using 1 bit for each possible InternalCookieEvent.
  int cookie_status_;

  // Indicates whether existing cookies were sent for this prerender, and
  // whether they were third-party cookies, and whether they were for blocking
  // resources. See the enum CookieSendType in prerender_contents.cc
  int cookie_send_type_;

  // Resources that are throttled, pending a prerender use. Can only access a
  // throttle on the IO thread.
  std::vector<base::WeakPtr<PrerenderResourceThrottle> > resource_throttles_;

  // A running tally of the number of bytes this prerender has caused to be
  // transferred over the network for resources.  Updated with AddNetworkBytes.
  int64 network_bytes_;

  DISALLOW_COPY_AND_ASSIGN(PrerenderContents);
};

}  // namespace prerender

#endif  // CHROME_BROWSER_PRERENDER_PRERENDER_CONTENTS_H_
