<!DOCTYPE html>
<!--
Copyright (c) 2015 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.
-->

<link rel="import" href="/tracing/model/user_model/load_expectation.html">

<script>
'use strict';

tr.exportTo('tr.importer', function() {
  // This global instant event marks the start of a navigation.
  var NAVIGATION_START = 'NavigationTiming navigationStart';

  // This render-process instant event marks the first contentful paint in a
  // main frame.
  var FIRST_CONTENTFUL_PAINT_TITLE = 'firstContentfulPaint';

  function getAllFrameEvents(modelHelper) {
    var frameEvents = [];
    frameEvents.push.apply(frameEvents,
        modelHelper.browserHelper.getFrameEventsInRange(
            tr.model.helpers.IMPL_FRAMETIME_TYPE, modelHelper.model.bounds));

    tr.b.iterItems(modelHelper.rendererHelpers, function(pid, renderer) {
      frameEvents.push.apply(frameEvents, renderer.getFrameEventsInRange(
          tr.model.helpers.IMPL_FRAMETIME_TYPE, modelHelper.model.bounds));
    });
    return frameEvents.sort(tr.importer.compareEvents);
  }

  // If a thread contains a typical initialization slice, then the first event
  // on that thread is a startup event.
  function getStartupEvents(modelHelper) {
    function isStartupSlice(slice) {
      return slice.title === 'BrowserMainLoop::CreateThreads';
    }
    var events = modelHelper.browserHelper.getAllAsyncSlicesMatching(
        isStartupSlice);
    var deduper = new tr.model.EventSet();
    events.forEach(function(event) {
      var sliceGroup = event.parentContainer.sliceGroup;
      var slice = sliceGroup && sliceGroup.findFirstSlice();
      if (slice)
        deduper.push(slice);
    });
    return deduper.toArray();
  }

  // Match every event in |openingEvents| to the first following event from
  // |closingEvents| and return an array containing a load interaction record
  // for each pair.
  function findLoadExpectationsInternal(
      modelHelper, subtypeName, openingEvents, closingEvents) {
    var loads = [];
    openingEvents.forEach(function(openingEvent) {
      closingEvents.forEach(function(closingEvent) {
        // Ignore opening event that already have a closing event.
        if (openingEvent.closingEvent)
          return;

        // Ignore closing events that already belong to an opening event.
        if (closingEvent.openingEvent)
          return;

        // Ignore closing events before |openingEvent|.
        if (closingEvent.start <= openingEvent.start)
          return;

        // Ignore events from different threads.
        if (openingEvent.parentContainer.parent.pid !==
              closingEvent.parentContainer.parent.pid)
          return;

        // This is the first closing event for this opening event, record it.
        openingEvent.closingEvent = closingEvent;
        closingEvent.openingEvent = openingEvent;
        var lir = new tr.model.um.LoadExpectation(
            modelHelper.model, subtypeName, openingEvent.start,
            closingEvent.end - openingEvent.start);
        lir.associatedEvents.push(openingEvent);
        lir.associatedEvents.push(closingEvent);
        loads.push(lir);
      });
    });
    return loads;
  }

  function findRenderLoadExpectations(modelHelper) {
    var events = [];
    modelHelper.model.iterateAllEvents(function(event) {
      if ((event.title === NAVIGATION_START) ||
          (event.title === FIRST_CONTENTFUL_PAINT_TITLE))
        events.push(event);
    });
    events.sort(tr.importer.compareEvents);

    var loads = [];
    var startEvent = undefined;
    events.forEach(function(event) {
      if (event.title === NAVIGATION_START) {
        startEvent = event;
      } else if (event.title === FIRST_CONTENTFUL_PAINT_TITLE) {
        if (startEvent) {
          loads.push(new tr.model.um.LoadExpectation(
              modelHelper.model, tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,
              startEvent.start, event.start - startEvent.start));
          startEvent = undefined;
        }
      }
    });

    // If the trace ended between navigation start and first contentful paint,
    // then make a LoadExpectation that ends at the end of the trace.
    if (startEvent) {
      loads.push(new tr.model.um.LoadExpectation(
            modelHelper.model, tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,
            startEvent.start, modelHelper.model.bounds.max - startEvent.start));
    }

    return loads;
  }

  // Match up RenderFrameImpl events with frame render events.
  function findLoadExpectations(modelHelper) {
    var loads = [];

    var commitLoadEvents =
        modelHelper.browserHelper.getCommitProvisionalLoadEventsInRange(
            modelHelper.model.bounds);

    // Attach frame events to every startup events.
    var startupEvents = getStartupEvents(modelHelper);
    var frameEvents = getAllFrameEvents(modelHelper);
    var startupLoads = findLoadExpectationsInternal(
        modelHelper, tr.model.um.LOAD_SUBTYPE_NAMES.STARTUP,
        startupEvents, frameEvents);
    loads.push.apply(loads, startupLoads);

    loads.push.apply(loads, findRenderLoadExpectations(modelHelper));

    return loads;
  }

  return {
    findLoadExpectations: findLoadExpectations
  };
});
</script>
