// Copyright 2021 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/dom/performance_resource_timing.h"

#include "cobalt/dom/performance.h"

namespace cobalt {
namespace dom {
namespace {
const char kPerformanceResourceTimingCacheMode[] = "local";
const uint64_t kPerformanceResourceTimingHeaderSize = 300;
}  // namespace

PerformanceResourceTiming::PerformanceResourceTiming(
    const std::string& name, DOMHighResTimeStamp start_time,
    DOMHighResTimeStamp end_time)
    : PerformanceEntry(name, start_time, end_time) {}

PerformanceResourceTiming::PerformanceResourceTiming(
    const net::LoadTimingInfo& timing_info, const std::string& initiator_type,
    const std::string& requested_url, Performance* performance,
    base::TimeTicks time_origin)
    : PerformanceEntry(requested_url,
                       Performance::MonotonicTimeToDOMHighResTimeStamp(
                           time_origin, timing_info.request_start),
                       Performance::MonotonicTimeToDOMHighResTimeStamp(
                           time_origin, timing_info.receive_headers_end)),
      initiator_type_(initiator_type),
      cache_mode_(kPerformanceResourceTimingCacheMode),
      timing_info_(timing_info),
      time_origin_(time_origin),
      timing_info_response_end_(performance->Now()) {}

std::string PerformanceResourceTiming::initiator_type() const {
  return initiator_type_;
}

DOMHighResTimeStamp PerformanceResourceTiming::fetch_start() const {
  if (timing_info_.request_start.is_null()) {
    return PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.request_start);
}

DOMHighResTimeStamp PerformanceResourceTiming::domain_lookup_start() const {
  if (timing_info_.connect_timing.dns_start.is_null()) {
    return PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.connect_timing.dns_start);
}

DOMHighResTimeStamp PerformanceResourceTiming::domain_lookup_end() const {
  if (timing_info_.connect_timing.dns_end.is_null()) {
    return PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.connect_timing.dns_end);
}

DOMHighResTimeStamp PerformanceResourceTiming::connect_start() const {
  if (timing_info_.connect_timing.connect_start.is_null()) {
    return PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.connect_timing.connect_start);
}

DOMHighResTimeStamp PerformanceResourceTiming::connect_end() const {
  if (timing_info_.connect_timing.connect_end.is_null()) {
    return PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.connect_timing.connect_end);
}

DOMHighResTimeStamp PerformanceResourceTiming::secure_connection_start() const {
  if (timing_info_.connect_timing.ssl_start.is_null()) {
    return 0.0;
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.connect_timing.ssl_start);
}

DOMHighResTimeStamp PerformanceResourceTiming::request_start() const {
  if (timing_info_.send_start.is_null()) {
    return PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.send_start);
}

DOMHighResTimeStamp PerformanceResourceTiming::response_start() const {
  if (timing_info_.receive_headers_end.is_null()) {
    PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.receive_headers_end);
}

DOMHighResTimeStamp PerformanceResourceTiming::response_end() const {
  return timing_info_response_end_;
}

uint64_t PerformanceResourceTiming::transfer_size() const {
  // Cobalt does not support cache mode.
  // The transferSize getter steps are to perform the following steps:
  //    https://www.w3.org/TR/resource-timing-2/#dom-performanceresourcetiming-transfersize
  // 1. If this's cache mode is "local", then return 0.
  // 2. If this's cache mode is "validated", then return 300.
  // 3. Return this's timing info's encoded body size plus 300.
  return timing_info_.encoded_body_size + kPerformanceResourceTimingHeaderSize;
}

uint64_t PerformanceResourceTiming::encoded_body_size() const {
  return timing_info_.encoded_body_size;
}

DOMHighResTimeStamp PerformanceResourceTiming::worker_start() const {
  if (timing_info_.service_worker_start_time.is_null()) {
    PerformanceEntry::start_time();
  }
  return Performance::MonotonicTimeToDOMHighResTimeStamp(
      time_origin_, timing_info_.service_worker_start_time);
}

void PerformanceResourceTiming::SetResourceTimingEntry(
    const net::LoadTimingInfo& timing_info, const std::string& initiator_type,
    const std::string& requested_url, const std::string& cache_mode) {
  // To setup the resource timing entry for PerformanceResourceTiming entry
  // given DOMString initiatorType, DOMString requestedURL, fetch timing info
  // timingInfo, and a DOMString cacheMode, perform the following steps:
  //   https://www.w3.org/TR/2021/WD-resource-timing-2-20210414/#dfn-setup-the-resource-timing-entry
  // 1. Assert that cacheMode is the empty string or "local".
  DCHECK(cache_mode.empty() || cache_mode == "local");
  // 2. Set entry's initiator type to initiatorType.
  initiator_type_ = initiator_type;
  // 3. Set entry's requested URL to requestedURL.
  requested_url_ = requested_url;
  // 4. Set entry's timing info to timingInfo.
  timing_info_ = timing_info;
  // 5. Set entry's cache mode to cacheMode.
  cache_mode_ = cache_mode;
}

}  // namespace dom
}  // namespace cobalt
