/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "public/web/WebPerformance.h"

#include "core/timing/Performance.h"

namespace blink {

static double millisecondsToSeconds(unsigned long long milliseconds) {
  return static_cast<double>(milliseconds / 1000.0);
}

void WebPerformance::reset() {
  m_private.reset();
}

void WebPerformance::assign(const WebPerformance& other) {
  m_private = other.m_private;
}

WebNavigationType WebPerformance::navigationType() const {
  switch (m_private->navigation()->type()) {
    case PerformanceNavigation::kTypeNavigate:
      return WebNavigationTypeOther;
    case PerformanceNavigation::kTypeReload:
      return WebNavigationTypeReload;
    case PerformanceNavigation::kTypeBackForward:
      return WebNavigationTypeBackForward;
    case PerformanceNavigation::kTypeReserved:
      return WebNavigationTypeOther;
  }
  NOTREACHED();
  return WebNavigationTypeOther;
}

double WebPerformance::navigationStart() const {
  return millisecondsToSeconds(m_private->timing()->navigationStart());
}

double WebPerformance::unloadEventEnd() const {
  return millisecondsToSeconds(m_private->timing()->unloadEventEnd());
}

double WebPerformance::redirectStart() const {
  return millisecondsToSeconds(m_private->timing()->redirectStart());
}

double WebPerformance::redirectEnd() const {
  return millisecondsToSeconds(m_private->timing()->redirectEnd());
}

unsigned short WebPerformance::redirectCount() const {
  return m_private->navigation()->redirectCount();
}

double WebPerformance::fetchStart() const {
  return millisecondsToSeconds(m_private->timing()->fetchStart());
}

double WebPerformance::domainLookupStart() const {
  return millisecondsToSeconds(m_private->timing()->domainLookupStart());
}

double WebPerformance::domainLookupEnd() const {
  return millisecondsToSeconds(m_private->timing()->domainLookupEnd());
}

double WebPerformance::connectStart() const {
  return millisecondsToSeconds(m_private->timing()->connectStart());
}

double WebPerformance::connectEnd() const {
  return millisecondsToSeconds(m_private->timing()->connectEnd());
}

double WebPerformance::requestStart() const {
  return millisecondsToSeconds(m_private->timing()->requestStart());
}

double WebPerformance::responseStart() const {
  return millisecondsToSeconds(m_private->timing()->responseStart());
}

double WebPerformance::responseEnd() const {
  return millisecondsToSeconds(m_private->timing()->responseEnd());
}

double WebPerformance::domLoading() const {
  return millisecondsToSeconds(m_private->timing()->domLoading());
}

double WebPerformance::domInteractive() const {
  return millisecondsToSeconds(m_private->timing()->domInteractive());
}

double WebPerformance::domContentLoadedEventStart() const {
  return millisecondsToSeconds(
      m_private->timing()->domContentLoadedEventStart());
}

double WebPerformance::domContentLoadedEventEnd() const {
  return millisecondsToSeconds(m_private->timing()->domContentLoadedEventEnd());
}

double WebPerformance::domComplete() const {
  return millisecondsToSeconds(m_private->timing()->domComplete());
}

double WebPerformance::loadEventStart() const {
  return millisecondsToSeconds(m_private->timing()->loadEventStart());
}

double WebPerformance::loadEventEnd() const {
  return millisecondsToSeconds(m_private->timing()->loadEventEnd());
}

double WebPerformance::firstLayout() const {
  return millisecondsToSeconds(m_private->timing()->firstLayout());
}

double WebPerformance::firstPaint() const {
  return millisecondsToSeconds(m_private->timing()->firstPaint());
}

double WebPerformance::firstTextPaint() const {
  return millisecondsToSeconds(m_private->timing()->firstTextPaint());
}

double WebPerformance::firstImagePaint() const {
  return millisecondsToSeconds(m_private->timing()->firstImagePaint());
}

double WebPerformance::firstContentfulPaint() const {
  return millisecondsToSeconds(m_private->timing()->firstContentfulPaint());
}

double WebPerformance::firstMeaningfulPaint() const {
  return millisecondsToSeconds(m_private->timing()->firstMeaningfulPaint());
}

double WebPerformance::parseStart() const {
  return millisecondsToSeconds(m_private->timing()->parseStart());
}

double WebPerformance::parseStop() const {
  return millisecondsToSeconds(m_private->timing()->parseStop());
}

double WebPerformance::parseBlockedOnScriptLoadDuration() const {
  return millisecondsToSeconds(
      m_private->timing()->parseBlockedOnScriptLoadDuration());
}

double WebPerformance::parseBlockedOnScriptLoadFromDocumentWriteDuration()
    const {
  return millisecondsToSeconds(
      m_private->timing()->parseBlockedOnScriptLoadFromDocumentWriteDuration());
}

double WebPerformance::parseBlockedOnScriptExecutionDuration() const {
  return millisecondsToSeconds(
      m_private->timing()->parseBlockedOnScriptExecutionDuration());
}

double WebPerformance::parseBlockedOnScriptExecutionFromDocumentWriteDuration()
    const {
  return millisecondsToSeconds(
      m_private->timing()
          ->parseBlockedOnScriptExecutionFromDocumentWriteDuration());
}

double WebPerformance::authorStyleSheetParseDurationBeforeFCP() const {
  return millisecondsToSeconds(
      m_private->timing()->authorStyleSheetParseDurationBeforeFCP());
}

double WebPerformance::updateStyleDurationBeforeFCP() const {
  return millisecondsToSeconds(
      m_private->timing()->updateStyleDurationBeforeFCP());
}

WebPerformance::WebPerformance(Performance* performance)
    : m_private(performance) {}

WebPerformance& WebPerformance::operator=(Performance* performance) {
  m_private = performance;
  return *this;
}

}  // namespace blink
