// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

class Timeline {
  #values;
  #selection;
  constructor() {
    this.#values = [];
    this.startTime = 0;
    this.endTime = 0;
  }
  get all(){
    return this.#values;
  }
  get selection(){
    return this.#selection;
  }
  set selection(value){
    this.#selection = value;
  }
  selectTimeRange(start, end){
    this.#selection =  this.filter(
      e => e.time >= start && e.time <= end);
  }
  getChunks(windowSizeMs){
    //TODO(zcankara) Fill this one
    return this.chunkSizes(windowSizeMs);
  }
  get values(){
    //TODO(zcankara) Not to break something delete later
    return this.#values;
  }

  count(filter) {
    return this.all.reduce((sum, each) => {
      return sum + (filter(each) === true ? 1 : 0);
    }, 0);
  }

  filter(predicate) {
    return this.all.filter(predicate);
  }

  push(event) {
    let time = event.time;
    if (!this.isEmpty() && this.last().time > time) {
      // Invalid insertion order, might happen without --single-process,
      // finding insertion point.
      let insertionPoint = this.find(time);
      this.#values.splice(insertionPoint, event);
    } else {
      this.#values.push(event);
    }
    if (time > 0) {
      this.endTime = Math.max(this.endTime, time);
      if (this.startTime === 0) {
        this.startTime = time;
      } else {
        this.startTime = Math.min(this.startTime, time);
      }
    }
  }

  at(index) {
    return this.#values[index];
  }

  isEmpty() {
    return this.size() === 0;
  }

  size() {
    return this.#values.length;
  }

  first() {
    return this.#values.first();
  }

  last() {
    return this.#values.last();
  }

  duration() {
    return this.last().time - this.first().time;
  }

  forEachChunkSize(count, fn) {
    const increment = this.duration() / count;
    let currentTime = this.first().time + increment;
    let index = 0;
    for (let i = 0; i < count; i++) {
      let nextIndex = this.find(currentTime, index);
      let nextTime = currentTime + increment;
      fn(index, nextIndex, currentTime, nextTime);
      index = nextIndex;
      currentTime = nextTime;
    }
  }

  chunkSizes(count) {
    let chunks = [];
    this.forEachChunkSize(count, (start, end) => chunks.push(end - start));
    return chunks;
  }

  chunks(count) {
    let chunks = [];
    this.forEachChunkSize(count, (start, end, startTime, endTime) => {
      let items = this.#values.slice(start, end);
      chunks.push(new Chunk(chunks.length, startTime, endTime, items));
    });
    return chunks;
  }

  range(start, end) {
    const first = this.find(start);
    if (first < 0) return [];
    const last = this.find(end, first);
    return this.#values.slice(first, last);
  }

  find(time, offset = 0) {
    return this.#find(this.#values, each => each.time - time, offset);
  }

  #find(array, cmp, offset = 0) {
    let min = offset;
    let max = array.length;
    while (min < max) {
      let mid = min + Math.floor((max - min) / 2);
      let result = cmp(array[mid]);
      if (result > 0) {
        max = mid - 1;
      } else {
        min = mid + 1;
      }
    }
    return min;
  }

  depthHistogram() {
    return this.#values.histogram(each => each.depth);
  }

  fanOutHistogram() {
    return this.#values.histogram(each => each.children.length);
  }

  forEach(fn) {
    return this.#values.forEach(fn);
  }
}

// ===========================================================================
class Chunk {
  constructor(index, start, end, items) {
    this.index = index;
    this.start = start;
    this.end = end;
    this.items = items;
    this.height = 0;
  }

  isEmpty() {
    return this.items.length === 0;
  }

  last() {
    return this.at(this.size() - 1);
  }

  first() {
    return this.at(0);
  }

  at(index) {
    return this.items[index];
  }

  size() {
    return this.items.length;
  }

  yOffset(event) {
    // items[0]   == oldest event, displayed at the top of the chunk
    // items[n-1] == youngest event, displayed at the bottom of the chunk
    return (1 - (this.indexOf(event) + 0.5) / this.size()) * this.height;
  }

  indexOf(event) {
    return this.items.indexOf(event);
  }

  has(event) {
    if (this.isEmpty()) return false;
    return this.first().time <= event.time && event.time <= this.last().time;
  }

  next(chunks) {
    return this.findChunk(chunks, 1);
  }

  prev(chunks) {
    return this.findChunk(chunks, -1);
  }

  findChunk(chunks, delta) {
    let i = this.index + delta;
    let chunk = chunks[i];
    while (chunk && chunk.size() === 0) {
      i += delta;
      chunk = chunks[i];
    }
    return chunk;
  }

  getBreakdown(event_fn){
    if (event_fn === void 0) {
      event_fn = each => each;
    }
    let breakdown = {__proto__: null};
    this.items.forEach(each => {
      const type = event_fn(each);
      const v = breakdown[type];
      breakdown[type] = (v | 0) + 1;
    });
    return Object.entries(breakdown).sort((a, b) => a[1] - b[1]);
  }

  filter(){
    return this.items.filter(map => !map.parent() || !this.has(map.parent()));
  }

}

export {Timeline, Chunk};
