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

#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
#include "chrome/browser/prerender/prerender_histograms.h"
#include "chrome/browser/prerender/prerender_manager.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/web_contents.h"

using content::WebContents;

DEFINE_WEB_CONTENTS_USER_DATA_KEY(prerender::PrerenderTabHelper);

namespace prerender {

PrerenderTabHelper::PrerenderTabHelper(content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents),
      origin_(ORIGIN_NONE),
      weak_factory_(this) {}

PrerenderTabHelper::~PrerenderTabHelper() {
}

void PrerenderTabHelper::DidGetRedirectForResourceRequest(
    const content::ResourceRedirectDetails& details) {
  if (details.resource_type != content::RESOURCE_TYPE_MAIN_FRAME)
    return;

  MainFrameUrlDidChange(details.new_url);
}

void PrerenderTabHelper::DidFinishNavigation(
      content::NavigationHandle* navigation_handle) {
  if (!navigation_handle->IsInMainFrame() ||
      !navigation_handle->HasCommitted() ||
      navigation_handle->IsErrorPage()) {
    return;
  }

  url_ = navigation_handle->GetURL();
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return;
  if (prerender_manager->IsWebContentsPrerendering(web_contents(), NULL))
    return;
  prerender_manager->RecordNavigation(url_);
}

void PrerenderTabHelper::DidStartNavigation(
    content::NavigationHandle* navigation_handle) {
  // Determine the origin.
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (prerender_manager)
    prerender_manager->IsWebContentsPrerendering(web_contents(), &origin_);

  if (navigation_handle->IsSameDocument())
    return;

  if (!navigation_handle->IsInMainFrame())
    return;

  MainFrameUrlDidChange(navigation_handle->GetURL());
}

void PrerenderTabHelper::MainFrameUrlDidChange(const GURL& url) {
  url_ = url;
}

PrerenderManager* PrerenderTabHelper::MaybeGetPrerenderManager() const {
  return PrerenderManagerFactory::GetForBrowserContext(
      web_contents()->GetBrowserContext());
}

base::TimeTicks PrerenderTabHelper::GetTimeTicksFromPrerenderManager() const {
  // Prerender browser tests should always have a PrerenderManager when mocking
  // out tick clock.
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (prerender_manager)
    return prerender_manager->GetCurrentTimeTicks();

  // Fall back to returning the same value as PrerenderManager would have
  // returned in production.
  return base::TimeTicks::Now();
}

bool PrerenderTabHelper::IsPrerendering() {
  PrerenderManager* prerender_manager = MaybeGetPrerenderManager();
  if (!prerender_manager)
    return false;
  return prerender_manager->IsWebContentsPrerendering(web_contents(), NULL);
}

void PrerenderTabHelper::PrerenderSwappedIn() {
  DCHECK(!IsPrerendering());
  swap_ticks_ = GetTimeTicksFromPrerenderManager();
}

}  // namespace prerender
