/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 * Copyright (C) 2012 Google Inc. All rights reserved.
 * Copyright (C) 2012 Intel 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 "config.h"
#include "PerformanceResourceTiming.h"

#include "Document.h"
#include "DocumentLoadTiming.h"
#include "DocumentLoader.h"
#include "PerformanceServerTiming.h"
#include "ResourceResponse.h"
#include "ResourceTiming.h"
#include <wtf/URL.h>

namespace WebCore {

static double networkLoadTimeToDOMHighResTimeStamp(MonotonicTime timeOrigin, MonotonicTime timeStamp)
{
    if (!timeStamp)
        return 0.0;
    ASSERT(timeOrigin);
    return Performance::reduceTimeResolution(timeStamp - timeOrigin).milliseconds();
}

static double fetchStart(MonotonicTime timeOrigin, const ResourceTiming& resourceTiming)
{
    if (auto fetchStart = resourceTiming.networkLoadMetrics().fetchStart)
        return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, fetchStart);

    // fetchStart is a required property.
    auto startTime = resourceTiming.resourceLoadTiming().startTime();
    ASSERT(startTime);
    return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, startTime);
}

static double entryStartTime(MonotonicTime timeOrigin, const ResourceTiming& resourceTiming)
{
    if (resourceTiming.networkLoadMetrics().failsTAOCheck
        || !resourceTiming.networkLoadMetrics().redirectCount)
        return fetchStart(timeOrigin, resourceTiming);

    if (resourceTiming.networkLoadMetrics().redirectStart)
        return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.networkLoadMetrics().redirectStart);

    return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.resourceLoadTiming().startTime());
}

static double entryEndTime(MonotonicTime timeOrigin, const ResourceTiming& resourceTiming)
{
    if (resourceTiming.networkLoadMetrics().responseEnd)
        return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.networkLoadMetrics().responseEnd);

    return networkLoadTimeToDOMHighResTimeStamp(timeOrigin, resourceTiming.resourceLoadTiming().endTime());
}

Ref<PerformanceResourceTiming> PerformanceResourceTiming::create(MonotonicTime timeOrigin, ResourceTiming&& resourceTiming)
{
    return adoptRef(*new PerformanceResourceTiming(timeOrigin, WTFMove(resourceTiming)));
}

PerformanceResourceTiming::PerformanceResourceTiming(MonotonicTime timeOrigin, ResourceTiming&& resourceTiming)
    : PerformanceEntry(resourceTiming.url().string(), entryStartTime(timeOrigin, resourceTiming), entryEndTime(timeOrigin, resourceTiming))
    , m_timeOrigin(timeOrigin)
    , m_resourceTiming(WTFMove(resourceTiming))
    , m_serverTiming(m_resourceTiming.populateServerTiming())
{
}

PerformanceResourceTiming::~PerformanceResourceTiming() = default;

const String& PerformanceResourceTiming::nextHopProtocol() const
{
    return m_resourceTiming.networkLoadMetrics().protocol;
}

double PerformanceResourceTiming::workerStart() const
{
    // FIXME: <https://webkit.org/b/179377> Implement PerformanceResourceTiming.workerStart in ServiceWorkers
    return 0.0;
}

double PerformanceResourceTiming::redirectStart() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (!m_resourceTiming.networkLoadMetrics().redirectCount)
        return 0.0;

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().redirectStart);
}

double PerformanceResourceTiming::redirectEnd() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (!m_resourceTiming.networkLoadMetrics().redirectCount)
        return 0.0;

    // These two times are so close to each other that we don't record two timestamps.
    // See https://www.w3.org/TR/resource-timing-2/#attribute-descriptions
    return fetchStart();
}

double PerformanceResourceTiming::fetchStart() const
{
    return WebCore::fetchStart(m_timeOrigin, m_resourceTiming);
}

double PerformanceResourceTiming::domainLookupStart() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (!m_resourceTiming.networkLoadMetrics().domainLookupStart)
        return fetchStart();

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().domainLookupStart);
}

double PerformanceResourceTiming::domainLookupEnd() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (!m_resourceTiming.networkLoadMetrics().domainLookupEnd)
        return domainLookupStart();

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().domainLookupEnd);
}

double PerformanceResourceTiming::connectStart() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (!m_resourceTiming.networkLoadMetrics().connectStart)
        return domainLookupEnd();

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().connectStart);
}

double PerformanceResourceTiming::connectEnd() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (!m_resourceTiming.networkLoadMetrics().connectEnd)
        return connectStart();

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().connectEnd);
}

double PerformanceResourceTiming::secureConnectionStart() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    if (m_resourceTiming.networkLoadMetrics().secureConnectionStart == reusedTLSConnectionSentinel)
        return fetchStart();

    if (!m_resourceTiming.networkLoadMetrics().secureConnectionStart)
        return 0.0;

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().secureConnectionStart);
}

double PerformanceResourceTiming::requestStart() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    // requestStart is 0 when a network request is not made.
    if (!m_resourceTiming.networkLoadMetrics().requestStart)
        return connectEnd();

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().requestStart);
}

double PerformanceResourceTiming::responseStart() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0.0;

    // responseStart is 0 when a network request is not made.
    if (!m_resourceTiming.networkLoadMetrics().responseStart)
        return requestStart();

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().responseStart);
}

double PerformanceResourceTiming::responseEnd() const
{
    // responseEnd is a required property, but PerformanceNavigationTiming
    // can be queried before the document load is complete
    ASSERT(m_resourceTiming.networkLoadMetrics().isComplete()
        || m_resourceTiming.resourceLoadTiming().endTime()
        || performanceEntryType() == Type::Navigation);

    if (m_resourceTiming.networkLoadMetrics().isComplete()) {
        if (m_resourceTiming.networkLoadMetrics().responseEnd)
            return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.networkLoadMetrics().responseEnd);

        // responseEnd is 0 when a network request is not made.
        // This should mean all other properties are empty.
        ASSERT(!m_resourceTiming.networkLoadMetrics().responseStart);
        ASSERT(!m_resourceTiming.networkLoadMetrics().requestStart);
        ASSERT(!m_resourceTiming.networkLoadMetrics().requestStart);
        ASSERT(!m_resourceTiming.networkLoadMetrics().secureConnectionStart);
        ASSERT(!m_resourceTiming.networkLoadMetrics().connectEnd);
        ASSERT(!m_resourceTiming.networkLoadMetrics().connectStart);
        ASSERT(!m_resourceTiming.networkLoadMetrics().domainLookupEnd);
        ASSERT(!m_resourceTiming.networkLoadMetrics().domainLookupStart);
    }

    return networkLoadTimeToDOMHighResTimeStamp(m_timeOrigin, m_resourceTiming.resourceLoadTiming().endTime());
}

uint64_t PerformanceResourceTiming::transferSize() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0;

    auto encodedBodySize = m_resourceTiming.networkLoadMetrics().responseBodyBytesReceived;
    if (encodedBodySize == std::numeric_limits<uint64_t>::max())
        return 0;

    // https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-transfersize
    return encodedBodySize + 300;
}

uint64_t PerformanceResourceTiming::encodedBodySize() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0;

    auto encodedBodySize = m_resourceTiming.networkLoadMetrics().responseBodyBytesReceived;
    if (encodedBodySize == std::numeric_limits<uint64_t>::max())
        return 0;

    return encodedBodySize;
}

uint64_t PerformanceResourceTiming::decodedBodySize() const
{
    if (m_resourceTiming.networkLoadMetrics().failsTAOCheck)
        return 0;

    auto decodedBodySize = m_resourceTiming.networkLoadMetrics().responseBodyDecodedSize;
    if (decodedBodySize == std::numeric_limits<uint64_t>::max())
        return 0;

    return decodedBodySize;
}

} // namespace WebCore
