/*
 * Copyright (C) 2015 Apple, 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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.
 */

#import "config.h"
#import "NetworkLoadMetrics.h"

#import "ResourceHandle.h"
#import <pal/spi/cocoa/NSURLConnectionSPI.h>

namespace WebCore {

static MonotonicTime dateToMonotonicTime(NSDate *date)
{
    if (auto interval = date.timeIntervalSince1970)
        return WallTime::fromRawSeconds(interval).approximateMonotonicTime();
    return { };
}

static Box<NetworkLoadMetrics> packageTimingData(MonotonicTime redirectStart, NSDate *fetchStart, NSDate *domainLookupStart, NSDate *domainLookupEnd, NSDate *connectStart, NSDate *secureConnectionStart, NSDate *connectEnd, NSDate *requestStart, NSDate *responseStart, bool reusedTLSConnection, NSString *protocol, uint16_t redirectCount, bool failsTAOCheck, bool hasCrossOriginRedirect)
{

    auto timing = Box<NetworkLoadMetrics>::create();

    timing->redirectStart = redirectStart;
    timing->fetchStart = dateToMonotonicTime(fetchStart);
    timing->domainLookupStart = dateToMonotonicTime(domainLookupStart);
    timing->domainLookupEnd = dateToMonotonicTime(domainLookupEnd);
    timing->connectStart = dateToMonotonicTime(connectStart);
    if (reusedTLSConnection && [protocol isEqualToString:@"https"])
        timing->secureConnectionStart = reusedTLSConnectionSentinel;
    else
        timing->secureConnectionStart = dateToMonotonicTime(secureConnectionStart);
    timing->connectEnd = dateToMonotonicTime(connectEnd);
    timing->requestStart = dateToMonotonicTime(requestStart);
    timing->responseStart = dateToMonotonicTime(responseStart);
    timing->redirectCount = redirectCount;
    timing->failsTAOCheck = failsTAOCheck;
    timing->hasCrossOriginRedirect = hasCrossOriginRedirect;

    // NOTE: responseEnd is not populated in this code path.

    return timing;
}

Box<NetworkLoadMetrics> copyTimingData(NSURLSessionTaskMetrics *incompleteMetrics, const NetworkLoadMetrics& metricsFromTask)
{
    NSArray<NSURLSessionTaskTransactionMetrics *> *transactionMetrics = incompleteMetrics.transactionMetrics;
    NSURLSessionTaskTransactionMetrics *metrics = transactionMetrics.lastObject;
    return packageTimingData(
        dateToMonotonicTime(transactionMetrics.firstObject.fetchStartDate),
        metrics.fetchStartDate,
        metrics.domainLookupStartDate,
        metrics.domainLookupEndDate,
        metrics.connectStartDate,
        metrics.secureConnectionStartDate,
        metrics.connectEndDate,
        metrics.requestStartDate,
        metrics.responseStartDate,
        metrics.reusedConnection,
        metrics.response.URL.scheme,
        incompleteMetrics.redirectCount,
        metricsFromTask.failsTAOCheck,
        metricsFromTask.hasCrossOriginRedirect
    );
}

Box<NetworkLoadMetrics> copyTimingData(NSURLConnection *connection, const ResourceHandle& handle)
{
    NSDictionary *timingData = [connection _timingData];

    auto timingValue = [&](NSString *key) -> RetainPtr<NSDate> {
        if (NSNumber *number = [timingData objectForKey:key]) {
            if (double doubleValue = number.doubleValue)
                return adoptNS([[NSDate alloc] initWithTimeIntervalSinceReferenceDate:doubleValue]);
        }
        return { };
    };

    auto data = packageTimingData(
        handle.startTimeBeforeRedirects(),
        timingValue(@"_kCFNTimingDataFetchStart").get(),
        timingValue(@"_kCFNTimingDataDomainLookupStart").get(),
        timingValue(@"_kCFNTimingDataDomainLookupEnd").get(),
        timingValue(@"_kCFNTimingDataConnectStart").get(),
        timingValue(@"_kCFNTimingDataSecureConnectionStart").get(),
        timingValue(@"_kCFNTimingDataConnectEnd").get(),
        timingValue(@"_kCFNTimingDataRequestStart").get(),
        timingValue(@"_kCFNTimingDataResponseStart").get(),
        timingValue(@"_kCFNTimingDataConnectionReused").get(),
        connection.currentRequest.URL.scheme,
        handle.redirectCount(),
        handle.failsTAOCheck(),
        handle.hasCrossOriginRedirect()
    );

    if (!data->fetchStart)
        data->fetchStart = data->redirectStart;

    return data;
}
    
}
