// 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.

import {LogEntry} from './log.mjs';

// ===========================================================================
// Map Log Events

const kChunkHeight = 200;
const kChunkWidth = 10;

function define(prototype, name, fn) {
  Object.defineProperty(prototype, name, {value: fn, enumerable: false});
}

define(Array.prototype, 'max', function(fn) {
  if (this.length === 0) return undefined;
  if (fn === undefined) fn = (each) => each;
  let max = fn(this[0]);
  for (let i = 1; i < this.length; i++) {
    max = Math.max(max, fn(this[i]));
  }
  return max;
})
define(Array.prototype, 'first', function() {
  return this[0]
});
define(Array.prototype, 'last', function() {
  return this[this.length - 1]
});

// ===========================================================================
// Map Log Events

class MapLogEntry extends LogEntry {
  edge = void 0;
  children = [];
  depth = 0;
  _isDeprecated = false;
  deprecatedTargets = null;
  leftId = 0;
  rightId = 0;
  filePosition = '';
  script = '';
  id = -1;
  constructor(id, time) {
    if (!time) throw new Error('Invalid time');
    super(id, time);
    MapLogEntry.set(id, this);
    this.id = id;
  }

  finalizeRootMap(id) {
    let stack = [this];
    while (stack.length > 0) {
      let current = stack.pop();
      if (current.leftId !== 0) {
        console.warn('Skipping potential parent loop between maps:', current)
        continue;
      }
      current.finalize(id)
      id += 1;
      current.children.forEach(edge => stack.push(edge.to))
      // TODO implement rightId
    }
    return id;
  }

  finalize(id) {
    // Initialize preorder tree traversal Ids for fast subtree inclusion checks
    if (id <= 0) throw 'invalid id';
    let currentId = id;
    this.leftId = currentId
  }

  parent() {
    if (this.edge === void 0) return void 0;
    return this.edge.from;
  }

  isDeprecated() {
    return this._isDeprecated;
  }

  deprecate() {
    this._isDeprecated = true;
  }

  isRoot() {
    return this.edge === void 0 || this.edge.from === void 0;
  }

  contains(map) {
    return this.leftId < map.leftId && map.rightId < this.rightId;
  }

  addEdge(edge) {
    this.children.push(edge);
  }

  chunkIndex(chunks) {
    // Did anybody say O(n)?
    for (let i = 0; i < chunks.length; i++) {
      let chunk = chunks[i];
      if (chunk.isEmpty()) continue;
      if (chunk.last().time < this.time) continue;
      return i;
    }
    return -1;
  }

  position(chunks) {
    let index = this.chunkIndex(chunks);
    let xFrom = (index + 1.5) * kChunkWidth;
    let yFrom = kChunkHeight - chunks[index].yOffset(this);
    return [xFrom, yFrom];
  }

  transitions() {
    let transitions = Object.create(null);
    let current = this;
    while (current) {
      let edge = current.edge;
      if (edge && edge.isTransition()) {
        transitions[edge.name] = edge;
      }
      current = current.parent()
    }
    return transitions;
  }

  get type() {
    return this.edge === void 0 ? 'new' : this.edge.type;
  }

  isBootstrapped() {
    return this.edge === void 0;
  }

  getParents() {
    let parents = [];
    let current = this.parent();
    while (current) {
      parents.push(current);
      current = current.parent();
    }
    return parents;
  }

  static get(id, time = undefined) {
    let maps = this.cache.get(id);
    if (maps) {
      for (let i = 1; i < maps.length; i++) {
        if (maps[i].time > time) {
          return maps[i - 1];
        }
      }
      // default return the latest
      return (maps.length > 0) ? maps[maps.length - 1] : undefined;
    }
  }

  static set(id, map) {
    if (this.cache.has(id)) {
      this.cache.get(id).push(map);
    } else {
      this.cache.set(id, [map]);
    }
  }
}

MapLogEntry.cache = new Map();

// ===========================================================================
class Edge {
  constructor(type, name, reason, time, from, to) {
    this.type = type;
    this.name = name;
    this.reason = reason;
    this.time = time;
    this.from = from;
    this.to = to;
  }

  finishSetup() {
    const from = this.from;
    if (from) from.addEdge(this);
    const to = this.to;
    if (to === undefined) return;
    to.edge = this;
    if (from === undefined) return;
    if (to === from) throw 'From and to must be distinct.';
    if (to.time < from.time) {
      console.warn('invalid time order');
    }
    let newDepth = from.depth + 1;
    if (to.depth > 0 && to.depth != newDepth) {
      console.warn('Depth has already been initialized');
    }
    to.depth = newDepth;
  }

  chunkIndex(chunks) {
    // Did anybody say O(n)?
    for (let i = 0; i < chunks.length; i++) {
      let chunk = chunks[i];
      if (chunk.isEmpty()) continue;
      if (chunk.last().time < this.time) continue;
      return i;
    }
    return -1;
  }

  parentEdge() {
    if (!this.from) return undefined;
    return this.from.edge;
  }

  chainLength() {
    let length = 0;
    let prev = this;
    while (prev) {
      prev = this.parent;
      length++;
    }
    return length;
  }

  isTransition() {
    return this.type === 'Transition'
  }

  isFastToSlow() {
    return this.type === 'Normalize'
  }

  isSlowToFast() {
    return this.type === 'SlowToFast'
  }

  isInitial() {
    return this.type === 'InitialMap'
  }

  isBootstrapped() {
    return this.type === 'new'
  }

  isReplaceDescriptors() {
    return this.type === 'ReplaceDescriptors'
  }

  isCopyAsPrototype() {
    return this.reason === 'CopyAsPrototype'
  }

  isOptimizeAsPrototype() {
    return this.reason === 'OptimizeAsPrototype'
  }

  symbol() {
    if (this.isTransition()) return '+';
    if (this.isFastToSlow()) return '⊡';
    if (this.isSlowToFast()) return '⊛';
    if (this.isReplaceDescriptors()) {
      if (this.name) return '+';
      return '∥';
    }
    return '';
  }

  toString() {
    let s = this.symbol();
    if (this.isTransition()) return s + this.name;
    if (this.isFastToSlow()) return s + this.reason;
    if (this.isCopyAsPrototype()) return s + 'Copy as Prototype';
    if (this.isOptimizeAsPrototype()) {
      return s + 'Optimize as Prototype';
    }
    if (this.isReplaceDescriptors() && this.name) {
      return this.type + ' ' + this.symbol() + this.name;
    }
    return this.type + ' ' + (this.reason ? this.reason : '') + ' ' +
        (this.name ? this.name : '')
  }
}

export {MapLogEntry, Edge, kChunkWidth, kChunkHeight};
