// Copyright (c) 2017 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.

/** @typedef {{startOffset: number, endOffset: number, count: number}} */
Coverage.RangeUseCount;

/** @typedef {{end: number, count: (number|undefined)}} */
Coverage.CoverageSegment;

/**
 * @enum {number}
 */
export const CoverageType = {
  CSS: (1 << 0),
  JavaScript: (1 << 1),
  JavaScriptPerFunction: (1 << 2),
};

/** @enum {symbol} */
export const SuspensionState = {
  Active: Symbol('Active'),
  Suspending: Symbol('Suspending'),
  Suspended: Symbol('Suspended')
};

/** @enum {symbol} */
export const Events = {
  CoverageUpdated: Symbol('CoverageUpdated'),
  CoverageReset: Symbol('CoverageReset'),
};

/** @type {number} */
const _coveragePollingPeriodMs = 200;

export default class CoverageModel extends SDK.SDKModel {
  /**
   * @param {!SDK.Target} target
   */
  constructor(target) {
    super(target);
    this._cpuProfilerModel = target.model(SDK.CPUProfilerModel);
    this._cssModel = target.model(SDK.CSSModel);
    this._debuggerModel = target.model(SDK.DebuggerModel);

    /** @type {!Map<string, !Coverage.URLCoverageInfo>} */
    this._coverageByURL = new Map();
    /** @type {!Map<!Common.ContentProvider, !Coverage.CoverageInfo>} */
    this._coverageByContentProvider = new Map();

    /** @type {!Coverage.SuspensionState} */
    this._suspensionState = SuspensionState.Active;
    /** @type {?number} */
    this._pollTimer = null;
    /** @type {?Promise} */
    this._currentPollPromise = null;
    /** @type {?boolean} */
    this._shouldResumePollingOnResume = false;
    /** @type {!Array<!{rawCoverageData:!Array<!Protocol.Profiler.ScriptCoverage>,stamp:number}>} */
    this._jsBacklog = [];
    /** @type {!Array<!{rawCoverageData:!Array<!Protocol.CSS.RuleUsage>,stamp:number}>} */
    this._cssBacklog = [];
    /** @type {?boolean} */
    this._performanceTraceRecording = false;
  }

  /**
   * @param {boolean} jsCoveragePerBlock - Collect per Block coverage if `true`, per function coverage otherwise.
   * @return {!Promise<boolean>}
   */
  async start(jsCoveragePerBlock) {
    if (this._suspensionState !== SuspensionState.Active) {
      throw Error('Cannot start CoverageModel while it is not active.');
    }
    const promises = [];
    if (this._cssModel) {
      // Note there's no JS coverage since JS won't ever return
      // coverage twice, even after it's restarted.
      this._clearCSS();

      this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._handleStyleSheetAdded, this);
      promises.push(this._cssModel.startCoverage());
    }
    if (this._cpuProfilerModel) {
      promises.push(this._cpuProfilerModel.startPreciseCoverage(jsCoveragePerBlock));
    }

    await Promise.all(promises);
    return !!(this._cssModel || this._cpuProfilerModel);
  }

  /**
   * @return {!Promise}
   */
  async stop() {
    await this.stopPolling();
    const promises = [];
    if (this._cpuProfilerModel) {
      promises.push(this._cpuProfilerModel.stopPreciseCoverage());
    }
    if (this._cssModel) {
      promises.push(this._cssModel.stopCoverage());
      this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetAdded, this._handleStyleSheetAdded, this);
    }
    await Promise.all(promises);
  }

  reset() {
    this._coverageByURL = new Map();
    this._coverageByContentProvider = new Map();
    this.dispatchEventToListeners(CoverageModel.Events.CoverageReset);
  }

  /**
   * @return {!Promise}
   */
  async startPolling() {
    if (this._currentPollPromise || this._suspensionState !== SuspensionState.Active) {
      return;
    }
    await this._pollLoop();
  }

  /**
   * @return {!Promise}
   */
  async _pollLoop() {
    this._clearTimer();
    this._currentPollPromise = this._pollAndCallback();
    await this._currentPollPromise;
    if (this._suspensionState === SuspensionState.Active || this._performanceTraceRecording) {
      this._pollTimer = setTimeout(() => this._pollLoop(), _coveragePollingPeriodMs);
    }
  }

  async stopPolling() {
    this._clearTimer();
    await this._currentPollPromise;
    this._currentPollPromise = null;
    // Do one last poll to get the final data.
    await this._pollAndCallback();
  }

  /**
   * @return {!Promise<undefined>}
   */
  async _pollAndCallback() {
    if (this._suspensionState === SuspensionState.Suspended && !this._performanceTraceRecording) {
      return;
    }
    const updates = await this._takeAllCoverage();
    // This conditional should never trigger, as all intended ways to stop
    // polling are awaiting the `_currentPollPromise` before suspending.
    console.assert(
        this._suspensionState !== SuspensionState.Suspended || this._performanceTraceRecording,
        'CoverageModel was suspended while polling.');
    if (updates.length) {
      this.dispatchEventToListeners(Events.CoverageUpdated, updates);
    }
  }

  _clearTimer() {
    if (this._pollTimer) {
      clearTimeout(this._pollTimer);
      this._pollTimer = null;
    }
  }

  /**
   * Stops polling as preparation for suspension. This function is idempotent
   * due because it changes the state to suspending.
   * @override
   * @param {string=} reason - optionally provide a reason, so the model can respond accordingly
   * @return {!Promise<undefined>}
   */
  async preSuspendModel(reason) {
    if (this._suspensionState !== SuspensionState.Active) {
      return;
    }
    this._suspensionState = SuspensionState.Suspending;
    if (reason === 'performance-timeline') {
      this._performanceTraceRecording = true;
      // Keep polling to the backlog if a performance trace is recorded.
      return;
    }
    if (this._currentPollPromise) {
      await this.stopPolling();
      this._shouldResumePollingOnResume = true;
    }
  }

  /**
   * @override
   * @param {string=} reason - optionally provide a reason, so the model can respond accordingly
   * @return {!Promise<undefined>}
   */
  async suspendModel(reason) {
    this._suspensionState = SuspensionState.Suspended;
  }

  /**
   * @override
   * @return {!Promise<undefined>}
   */
  async resumeModel() {
  }

  /**
   * Restarts polling after suspension. Note that the function is idempotent
   * because starting polling is idempotent.
   * @override
   * @return {!Promise<undefined>}
   */
  async postResumeModel() {
    this._suspensionState = SuspensionState.Active;
    this._performanceTraceRecording = false;
    if (this._shouldResumePollingOnResume) {
      this._shouldResumePollingOnResume = false;
      await this.startPolling();
    }
  }

  /**
   * @return {!Array<!Coverage.URLCoverageInfo>}
   */
  entries() {
    return Array.from(this._coverageByURL.values());
  }

  /**
   *
   * @param {string} url
   * @return {?Coverage.URLCoverageInfo}
   */
  getCoverageForUrl(url) {
    return this._coverageByURL.get(url);
  }

  /**
   * @param {!Common.ContentProvider} contentProvider
   * @param {number} startOffset
   * @param {number} endOffset
   * @return {boolean|undefined}
   */
  usageForRange(contentProvider, startOffset, endOffset) {
    const coverageInfo = this._coverageByContentProvider.get(contentProvider);
    return coverageInfo && coverageInfo.usageForRange(startOffset, endOffset);
  }

  _clearCSS() {
    for (const entry of this._coverageByContentProvider.values()) {
      if (entry.type() !== CoverageType.CSS) {
        continue;
      }
      const contentProvider = /** @type {!SDK.CSSStyleSheetHeader} */ (entry.contentProvider());
      this._coverageByContentProvider.delete(contentProvider);
      const key = `${contentProvider.startLine}:${contentProvider.startColumn}`;
      const urlEntry = this._coverageByURL.get(entry.url());
      if (!urlEntry || !urlEntry._coverageInfoByLocation.delete(key)) {
        continue;
      }
      urlEntry._addToSizes(-entry._usedSize, -entry._size);
      if (!urlEntry._coverageInfoByLocation.size) {
        this._coverageByURL.delete(entry.url());
      }
    }

    for (const styleSheetHeader of this._cssModel.getAllStyleSheetHeaders()) {
      this._addStyleSheetToCSSCoverage(styleSheetHeader);
    }
  }

  /**
   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
   */
  async _takeAllCoverage() {
    const [updatesCSS, updatesJS] = await Promise.all([this._takeCSSCoverage(), this._takeJSCoverage()]);
    return [...updatesCSS, ...updatesJS];
  }

  /**
   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
   */
  async _takeJSCoverage() {
    if (!this._cpuProfilerModel) {
      return [];
    }
    const now = Date.now();
    const freshRawCoverageData = await this._cpuProfilerModel.takePreciseCoverage();
    if (this._suspensionState !== SuspensionState.Active) {
      if (freshRawCoverageData.length > 0) {
        this._jsBacklog.push({rawCoverageData: freshRawCoverageData, stamp: now});
      }

      return [];
    }
    const results = [];
    for (const {rawCoverageData, stamp} of this._jsBacklog) {
      results.push(this._processJSCoverage(rawCoverageData, stamp));
    }

    this._jsBacklog = [];
    if (freshRawCoverageData.length > 0) {
      results.push(this._processJSCoverage(freshRawCoverageData, now));
    }
    return results.flat();
  }

  /**
   * @param {!Array<!Protocol.Profiler.ScriptCoverage>} scriptsCoverage
   * @return {!Array<!Coverage.CoverageInfo>}
   */
  _processJSCoverage(scriptsCoverage, stamp) {
    const updatedEntries = [];
    for (const entry of scriptsCoverage) {
      const script = this._debuggerModel.scriptForId(entry.scriptId);
      if (!script) {
        continue;
      }

      const ranges = [];
      let type = CoverageType.JavaScript;
      for (const func of entry.functions) {
        // Do not coerce undefined to false, i.e. only consider blockLevel to be false
        // if back-end explicitly provides blockLevel field, otherwise presume blockLevel
        // coverage is not available. Also, ignore non-block level functions that weren't
        // ever called.
        if (func.isBlockCoverage === false && !(func.ranges.length === 1 && !func.ranges[0].count)) {
          type |= CoverageType.JavaScriptPerFunction;
        }
        for (const range of func.ranges) {
          ranges.push(range);
        }
      }
      const subentry = this._addCoverage(
          script, script.contentLength, script.lineOffset, script.columnOffset, ranges,
          /** @type {!Coverage.CoverageType} */ (type), stamp);
      if (subentry) {
        updatedEntries.push(subentry);
      }
    }
    return updatedEntries;
  }

  _handleStyleSheetAdded(event) {
    const styleSheetHeader = /** @type {!SDK.CSSStyleSheetHeader} */ (event.data);

    this._addStyleSheetToCSSCoverage(styleSheetHeader);
  }

  /**
   * @return {!Promise<!Array<!Coverage.CoverageInfo>>}
   */
  async _takeCSSCoverage() {
    if (!this._cssModel) {
      return [];
    }
    const now = Date.now();
    const freshRawCoverageData = await this._cssModel.takeCoverageDelta();
    if (this._suspensionState !== SuspensionState.Active) {
      if (freshRawCoverageData.length > 0) {
        this._cssBacklog.push({rawCoverageData: freshRawCoverageData, stamp: now});
      }

      return [];
    }
    const results = [];
    for (const {rawCoverageData, stamp} of this._cssBacklog) {
      results.push(this._processCSSCoverage(rawCoverageData, stamp));
    }

    this._cssBacklog = [];
    if (freshRawCoverageData.length > 0) {
      results.push(this._processCSSCoverage(freshRawCoverageData, now));
    }
    return results.flat();
  }

  /**
   * @param {!Array<!Protocol.CSS.RuleUsage>} ruleUsageList
   * @return {!Array<!Coverage.CoverageInfo>}
   */
  _processCSSCoverage(ruleUsageList, stamp) {
    const updatedEntries = [];
    /** @type {!Map<!SDK.CSSStyleSheetHeader, !Array<!Coverage.RangeUseCount>>} */
    const rulesByStyleSheet = new Map();
    for (const rule of ruleUsageList) {
      const styleSheetHeader = this._cssModel.styleSheetHeaderForId(rule.styleSheetId);
      if (!styleSheetHeader) {
        continue;
      }
      let ranges = rulesByStyleSheet.get(styleSheetHeader);
      if (!ranges) {
        ranges = [];
        rulesByStyleSheet.set(styleSheetHeader, ranges);
      }
      ranges.push({startOffset: rule.startOffset, endOffset: rule.endOffset, count: Number(rule.used)});
    }
    for (const entry of rulesByStyleSheet) {
      const styleSheetHeader = /** @type {!SDK.CSSStyleSheetHeader} */ (entry[0]);
      const ranges = /** @type {!Array<!Coverage.RangeUseCount>} */ (entry[1]);
      const subentry = this._addCoverage(
          styleSheetHeader, styleSheetHeader.contentLength, styleSheetHeader.startLine, styleSheetHeader.startColumn,
          ranges, CoverageType.CSS, stamp);
      if (subentry) {
        updatedEntries.push(subentry);
      }
    }
    return updatedEntries;
  }

  /**
   * @param {!Array<!Coverage.RangeUseCount>} ranges
   * @return {!Array<!Coverage.CoverageSegment>}
   */
  static _convertToDisjointSegments(ranges, stamp) {
    ranges.sort((a, b) => a.startOffset - b.startOffset);

    const result = [];
    const stack = [];
    for (const entry of ranges) {
      let top = stack.peekLast();
      while (top && top.endOffset <= entry.startOffset) {
        append(top.endOffset, top.count);
        stack.pop();
        top = stack.peekLast();
      }
      append(entry.startOffset, top ? top.count : undefined);
      stack.push(entry);
    }

    while (stack.length) {
      const top = stack.pop();
      append(top.endOffset, top.count);
    }

    /**
     * @param {number} end
     * @param {number} count
     */
    function append(end, count) {
      const last = result.peekLast();
      if (last) {
        if (last.end === end) {
          return;
        }
        if (last.count === count) {
          last.end = end;
          return;
        }
      }
      result.push({end: end, count: count, stamp: stamp});
    }

    return result;
  }

  /**
   * @param {!SDK.CSSStyleSheetHeader} styleSheetHeader
   */
  _addStyleSheetToCSSCoverage(styleSheetHeader) {
    this._addCoverage(
        styleSheetHeader, styleSheetHeader.contentLength, styleSheetHeader.startLine, styleSheetHeader.startColumn, [],
        CoverageType.CSS, Date.now());
  }

  /**
   * @param {!Common.ContentProvider} contentProvider
   * @param {number} contentLength
   * @param {number} startLine
   * @param {number} startColumn
   * @param {!Array<!Coverage.RangeUseCount>} ranges
   * @param {!Coverage.CoverageType} type
   * @return {?Coverage.CoverageInfo}
   */
  _addCoverage(contentProvider, contentLength, startLine, startColumn, ranges, type, stamp) {
    const url = contentProvider.contentURL();
    if (!url) {
      return null;
    }
    let urlCoverage = this._coverageByURL.get(url);
    let isNewUrlCoverage = false;
    if (!urlCoverage) {
      isNewUrlCoverage = true;
      urlCoverage = new Coverage.URLCoverageInfo(url);
      this._coverageByURL.set(url, urlCoverage);
    }

    const coverageInfo = urlCoverage._ensureEntry(contentProvider, contentLength, startLine, startColumn, type);
    this._coverageByContentProvider.set(contentProvider, coverageInfo);
    const segments = Coverage.CoverageModel._convertToDisjointSegments(ranges, stamp);
    if (segments.length && segments.peekLast().end < contentLength) {
      segments.push({end: contentLength, stamp: stamp});
    }
    const oldUsedSize = coverageInfo._usedSize;
    coverageInfo.mergeCoverage(segments);
    if (!isNewUrlCoverage && coverageInfo._usedSize === oldUsedSize) {
      return null;
    }
    urlCoverage._addToSizes(coverageInfo._usedSize - oldUsedSize, 0);
    return coverageInfo;
  }

  /**
   * @param {!Bindings.FileOutputStream} fos
   */
  async exportReport(fos) {
    const result = [];
    function locationCompare(a, b) {
      const [aLine, aPos] = a.split(':');
      const [bLine, bPos] = b.split(':');
      return aLine - bLine || aPos - bPos;
    }
    const coverageByUrlKeys = Array.from(this._coverageByURL.keys()).sort();
    for (const urlInfoKey of coverageByUrlKeys) {
      const urlInfo = this._coverageByURL.get(urlInfoKey);
      const url = urlInfo.url();
      if (url.startsWith('extensions::') || url.startsWith('chrome-extension://')) {
        continue;
      }

      // For .html resources, multiple scripts share URL, but have different offsets.
      let useFullText = false;
      for (const info of urlInfo._coverageInfoByLocation.values()) {
        if (info._lineOffset || info._columnOffset) {
          useFullText = !!url;
          break;
        }
      }

      let fullText = null;
      if (useFullText) {
        const resource = SDK.ResourceTreeModel.resourceForURL(url);
        const content = (await resource.requestContent()).content;
        fullText = resource ? new TextUtils.Text(content || '') : null;
      }

      const coverageByLocationKeys = Array.from(urlInfo._coverageInfoByLocation.keys()).sort(locationCompare);

      // We have full text for this resource, resolve the offsets using the text line endings.
      if (fullText) {
        const entry = {url, ranges: [], text: fullText.value()};
        for (const infoKey of coverageByLocationKeys) {
          const info = urlInfo._coverageInfoByLocation.get(infoKey);
          const offset = fullText ? fullText.offsetFromPosition(info._lineOffset, info._columnOffset) : 0;
          let start = 0;
          for (const segment of info._segments) {
            if (segment.count) {
              entry.ranges.push({start: start + offset, end: segment.end + offset});
            } else {
              start = segment.end;
            }
          }
        }
        result.push(entry);
        continue;
      }

      // Fall back to the per-script operation.
      for (const infoKey of coverageByLocationKeys) {
        const info = urlInfo._coverageInfoByLocation.get(infoKey);
        const entry = {url, ranges: [], text: (await info.contentProvider().requestContent()).content};
        let start = 0;
        for (const segment of info._segments) {
          if (segment.count) {
            entry.ranges.push({start: start, end: segment.end});
          } else {
            start = segment.end;
          }
        }
        result.push(entry);
      }
    }
    await fos.write(JSON.stringify(result, undefined, 2));
    fos.close();
  }
}

SDK.SDKModel.register(CoverageModel, SDK.Target.Capability.None, false);

/**
 * @unrestricted
 */
export class URLCoverageInfo extends Common.Object {
  /**
   * @param {string} url
   */
  constructor(url) {
    super();

    this._url = url;
    /** @type {!Map<string, !Coverage.CoverageInfo>} */
    this._coverageInfoByLocation = new Map();
    this._size = 0;
    this._usedSize = 0;
    /** @type {!Coverage.CoverageType} */
    this._type;
    this._isContentScript = false;
  }

  /**
   * @return {string}
   */
  url() {
    return this._url;
  }

  /**
   * @return {!Coverage.CoverageType}
   */
  type() {
    return this._type;
  }

  /**
   * @return {number}
   */
  size() {
    return this._size;
  }

  /**
   * @return {number}
   */
  usedSize() {
    return this._usedSize;
  }

  /**
   * @return {number}
   */
  unusedSize() {
    return this._size - this._usedSize;
  }

  /**
   * @return {number}
   */
  usedPercentage() {
    // Per convention, empty files are reported as 100 % uncovered
    if (this._size === 0) {
      return 0;
    }
    return this.usedSize() / this.size() * 100;
  }

  /**
   * @return {number}
   */
  unusedPercentage() {
    // Per convention, empty files are reported as 100 % uncovered
    if (this._size === 0) {
      return 100;
    }
    return this.unusedSize() / this.size() * 100;
  }

  /**
   * @return {boolean}
   */
  isContentScript() {
    return this._isContentScript;
  }

  entries() {
    return this._coverageInfoByLocation.values();
  }

  _addToSizes(usedSize, size) {
    this._usedSize += usedSize;
    this._size += size;

    if (usedSize !== 0 || size !== 0) {
      this.dispatchEventToListeners(Coverage.URLCoverageInfo.Events.SizesChanged);
    }
  }

  /**
   * @param {!Common.ContentProvider} contentProvider
   * @param {number} contentLength
   * @param {number} lineOffset
   * @param {number} columnOffset
   * @param {!Coverage.CoverageType} type
   * @return {!Coverage.CoverageInfo}
   */
  _ensureEntry(contentProvider, contentLength, lineOffset, columnOffset, type) {
    const key = `${lineOffset}:${columnOffset}`;
    let entry = this._coverageInfoByLocation.get(key);

    if ((type & CoverageType.JavaScript) && !this._coverageInfoByLocation.size) {
      this._isContentScript = /** @type {!SDK.Script} */ (contentProvider).isContentScript();
    }
    this._type |= type;

    if (entry) {
      entry._coverageType |= type;
      return entry;
    }

    if ((type & CoverageType.JavaScript) && !this._coverageInfoByLocation.size) {
      this._isContentScript = /** @type {!SDK.Script} */ (contentProvider).isContentScript();
    }

    entry = new Coverage.CoverageInfo(contentProvider, contentLength, lineOffset, columnOffset, type);
    this._coverageInfoByLocation.set(key, entry);
    this._addToSizes(0, contentLength);

    return entry;
  }
}

/** @enum {symbol} */
URLCoverageInfo.Events = {
  SizesChanged: Symbol('SizesChanged')
};

/**
 * @unrestricted
 */
export class CoverageInfo {
  /**
   * @param {!Common.ContentProvider} contentProvider
   * @param {number} size
   * @param {number} lineOffset
   * @param {number} columnOffset
   * @param {!Coverage.CoverageType} type
   */
  constructor(contentProvider, size, lineOffset, columnOffset, type) {
    this._contentProvider = contentProvider;
    this._size = size;
    this._usedSize = 0;
    this._statsByTimestamp = new Map();
    this._lineOffset = lineOffset;
    this._columnOffset = columnOffset;
    this._coverageType = type;

    /** !Array<!Coverage.CoverageSegment> */
    this._segments = [];
  }

  /**
   * @return {!Common.ContentProvider}
   */
  contentProvider() {
    return this._contentProvider;
  }

  /**
   * @return {string}
   */
  url() {
    return this._contentProvider.contentURL();
  }

  /**
   * @return {!Coverage.CoverageType}
   */
  type() {
    return this._coverageType;
  }

  /**
   * @param {!Array<!Coverage.CoverageSegment>} segments
   */
  mergeCoverage(segments) {
    this._segments = Coverage.CoverageInfo._mergeCoverage(this._segments, segments);
    this._updateStats();
  }

  usedByTimestamp() {
    return this._statsByTimestamp;
  }

  size() {
    return this._size;
  }

  /**
   * @param {number} start
   * @param {number} end
   * @return {boolean}
   */
  usageForRange(start, end) {
    let index = this._segments.upperBound(start, (position, segment) => position - segment.end);
    for (; index < this._segments.length && this._segments[index].end < end; ++index) {
      if (this._segments[index].count) {
        return true;
      }
    }
    return index < this._segments.length && !!this._segments[index].count;
  }

  /**
   * @param {!Array<!Coverage.CoverageSegment>} segmentsA
   * @param {!Array<!Coverage.CoverageSegment>} segmentsB
   */
  static _mergeCoverage(segmentsA, segmentsB) {
    const result = [];

    let indexA = 0;
    let indexB = 0;
    while (indexA < segmentsA.length && indexB < segmentsB.length) {
      const a = segmentsA[indexA];
      const b = segmentsB[indexB];
      const count =
          typeof a.count === 'number' || typeof b.count === 'number' ? (a.count || 0) + (b.count || 0) : undefined;
      const end = Math.min(a.end, b.end);
      const last = result.peekLast();
      const stamp = Math.min(a.stamp, b.stamp);
      if (!last || last.count !== count || last.stamp !== stamp) {
        result.push({end: end, count: count, stamp: stamp});
      } else {
        last.end = end;
      }
      if (a.end <= b.end) {
        indexA++;
      }
      if (a.end >= b.end) {
        indexB++;
      }
    }

    for (; indexA < segmentsA.length; indexA++) {
      result.push(segmentsA[indexA]);
    }
    for (; indexB < segmentsB.length; indexB++) {
      result.push(segmentsB[indexB]);
    }
    return result;
  }

  _updateStats() {
    this._statsByTimestamp = new Map();
    this._usedSize = 0;

    let last = 0;
    for (const segment of this._segments) {
      if (!this._statsByTimestamp.has(segment.stamp)) {
        this._statsByTimestamp.set(segment.stamp, 0);
      }

      if (segment.count) {
        const used = segment.end - last;
        this._usedSize += used;
        this._statsByTimestamp.set(segment.stamp, this._statsByTimestamp.get(segment.stamp) + used);
      }
      last = segment.end;
    }
  }
}

/* Legacy exported object */
self.Coverage = self.Coverage || {};

/* Legacy exported object */
Coverage = Coverage || {};

/**
 * @constructor
 */
Coverage.CoverageModel = CoverageModel;

/** @enum {symbol} */
Coverage.CoverageModel.Events = Events;

/**
 * @enum {number}
 */
Coverage.CoverageType = CoverageType;

/** @enum {symbol} */
Coverage.SuspensionState = SuspensionState;

/**
 * @constructor
 */
Coverage.URLCoverageInfo = URLCoverageInfo;

/**
 * @constructor
 */
Coverage.CoverageInfo = CoverageInfo;
