/*
 * Copyright (C) 2010 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.
 */

// https://w3c.github.io/hr-time/#the-performance-interface

// TODO(philipj): This interface should be [Exposed=(Window,Worker)]. Doing that
// would allow the WorkerPerformance interface to be merged into this.
// TODO(philipj): None of the optional DOMString arguments in this interface
// should have a default value.
[
  GarbageCollected
] interface Performance : EventTarget {
    DOMHighResTimeStamp now();

    // Performance Timeline
    // https://w3c.github.io/performance-timeline/#the-performance-interface
    // TODO(philipj): getEntries() should take an optional FilterOptions argument.
    [MeasureAs=UnprefixedPerformanceTimeline] PerformanceEntryList getEntries();
    [MeasureAs=UnprefixedPerformanceTimeline] PerformanceEntryList getEntriesByType(DOMString entryType);
    [MeasureAs=UnprefixedPerformanceTimeline] PerformanceEntryList getEntriesByName(DOMString name, optional DOMString entryType = null);

    // Resource Timing
    // https://w3c.github.io/resource-timing/#extensions-performance-interface
    void clearResourceTimings();
    void setResourceTimingBufferSize(unsigned long maxSize);
    attribute EventHandler onresourcetimingbufferfull;

    // TODO(ksakamoto): Remove these prefixed APIs.
    [DeprecateAs=PrefixedPerformanceClearResourceTimings, ImplementedAs=clearResourceTimings] void webkitClearResourceTimings();
    [DeprecateAs=PrefixedPerformanceSetResourceTimingBufferSize, ImplementedAs=setResourceTimingBufferSize] void webkitSetResourceTimingBufferSize(unsigned long maxSize);
    [DeprecateAs=PrefixedPerformanceResourceTimingBufferFull] attribute EventHandler onwebkitresourcetimingbufferfull;

    // Navigation Timing
    // https://w3c.github.io/navigation-timing/#extensions-to-the-performance-interface
    [SameObject, Measure] readonly attribute PerformanceTiming timing;
    [SameObject, Measure] readonly attribute PerformanceNavigation navigation;

    // User Timing
    // https://w3c.github.io/user-timing/#extensions-performance-interface
    [MeasureAs=UnprefixedUserTiming, RaisesException] void mark(DOMString markName);
    [MeasureAs=UnprefixedUserTiming] void clearMarks(optional DOMString markName = null);

    [MeasureAs=UnprefixedUserTiming, RaisesException] void measure(DOMString measureName, optional DOMString startMark = null, optional DOMString endMark = null);
    [MeasureAs=UnprefixedUserTiming] void clearMeasures(optional DOMString measureName = null);

    // Frame Timing
    // https://w3c.github.io/frame-timing/#extensions-performance-interface
    [RuntimeEnabled=FrameTimingSupport, MeasureAs=PerformanceFrameTiming] void clearFrameTimings();
    [RuntimeEnabled=FrameTimingSupport, MeasureAs=PerformanceFrameTiming] void setFrameTimingBufferSize(unsigned long maxSize);
    [RuntimeEnabled=FrameTimingSupport] attribute EventHandler onframetimingbufferfull;

    // TODO(philipj): There is no spec for the Memory Info API, see blink-dev:
    // https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
    [Measure] readonly attribute MemoryInfo memory;
};
