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

#include <algorithm>

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "chrome/browser/prerender/prerender_contents.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"

using content::BrowserThread;

namespace prerender {

PrerenderHandle::Observer::Observer() {
}

PrerenderHandle::Observer::~Observer() {
}

PrerenderHandle::~PrerenderHandle() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (prerender_data_) {
    prerender_data_->contents()->RemoveObserver(this);
  }
}

void PrerenderHandle::SetObserver(Observer* observer) {
  DCHECK(observer);
  observer_ = observer;
}

void PrerenderHandle::OnNavigateAway() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (prerender_data_)
    prerender_data_->OnHandleNavigatedAway(this);
}

void PrerenderHandle::OnCancel() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (prerender_data_)
    prerender_data_->OnHandleCanceled(this);
}

bool PrerenderHandle::IsPrerendering() const {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return prerender_data_.get() != nullptr;
}

bool PrerenderHandle::IsFinishedLoading() const {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return prerender_data_ && prerender_data_->contents()->has_finished_loading();
}

bool PrerenderHandle::IsAbandoned() const {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return prerender_data_ && !prerender_data_->abandon_time().is_null();
}

PrerenderContents* PrerenderHandle::contents() const {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return prerender_data_ ? prerender_data_->contents() : nullptr;
}

bool PrerenderHandle::Matches(
    const GURL& url,
    const content::SessionStorageNamespace* session_storage_namespace) const {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  return prerender_data_ &&
         prerender_data_->contents()->Matches(url, session_storage_namespace);
}

PrerenderHandle::PrerenderHandle(
    PrerenderManager::PrerenderData* prerender_data)
    : observer_(nullptr), weak_ptr_factory_(this) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (prerender_data) {
    prerender_data_ = prerender_data->AsWeakPtr();
    prerender_data->OnHandleCreated(this);
  }
}

void PrerenderHandle::OnPrerenderStart(PrerenderContents* prerender_contents) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(prerender_data_);
  DCHECK_EQ(prerender_data_->contents(), prerender_contents);
  if (observer_)
    observer_->OnPrerenderStart(this);
}

void PrerenderHandle::OnPrerenderStopLoading(
    PrerenderContents* prerender_contents) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(prerender_data_);
  DCHECK_EQ(prerender_data_->contents(), prerender_contents);
  if (observer_)
    observer_->OnPrerenderStopLoading(this);
}

void PrerenderHandle::OnPrerenderDomContentLoaded(
    PrerenderContents* prerender_contents) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(prerender_data_);
  DCHECK_EQ(prerender_data_->contents(), prerender_contents);
  if (observer_)
    observer_->OnPrerenderDomContentLoaded(this);
}

void PrerenderHandle::OnPrerenderStop(PrerenderContents* prerender_contents) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (observer_)
    observer_->OnPrerenderStop(this);
}

bool PrerenderHandle::RepresentingSamePrerenderAs(
    PrerenderHandle* other) const {
  return other && other->prerender_data_ && prerender_data_ &&
         prerender_data_.get() == other->prerender_data_.get();
}

}  // namespace prerender
