// Copyright 2017 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 MapProcessor extends LogReader {
  constructor() {
    super();
    this.dispatchTable_ = {
      'code-creation': {
        parsers: [parseString, parseInt, parseInt, parseInt, parseInt,
          parseString, parseVarArgs],
        processor: this.processCodeCreation
      },
      'code-move': {
        parsers: [parseInt, parseInt],
        'sfi-move': {
          parsers: [parseInt, parseInt],
          processor: this.processCodeMove
        },
        'code-delete': {
          parsers: [parseInt],
          processor: this.processCodeDelete
        },
        processor: this.processFunctionMove
      },
      'map-create': {
        parsers: [parseInt, parseInt, parseString],
        processor: this.processMapCreate
      },
      'map': {
        parsers: [parseString, parseInt, parseInt, parseInt, parseInt, parseInt,
          parseString, parseString, parseString
        ],
        processor: this.processMap
      },
      'map-details': {
        parsers: [parseInt, parseInt, parseString],
        processor: this.processMapDetails
      }
    };
    this.profile_ = new Profile();
    this.timeline_ = new Timeline();
  }

  printError(str) {
    console.error(str);
    throw str
  }

  processString(string) {
    let end = string.length;
    let current = 0;
    let next = 0;
    let line;
    let i = 0;
    let entry;
    try {
      while (current < end) {
        next = string.indexOf("\n", current);
        if (next === -1) break;
        i++;
        line = string.substring(current, next);
        current = next + 1;
        this.processLogLine(line);
      }
    } catch(e) {
      console.error("Error occurred during parsing, trying to continue: " + e);
    }
    return this.finalize();
  }

  processLogFile(fileName) {
    this.collectEntries = true
    this.lastLogFileName_ = fileName;
    let line;
    while (line = readline()) {
      this.processLogLine(line);
    }
    return this.finalize();
  }

  finalize() {
    // TODO(cbruni): print stats;
    this.timeline_.finalize();
    return this.timeline_;
  }

  addEntry(entry) {
    this.entries.push(entry);
  }

  /**
   * Parser for dynamic code optimization state.
   */
  parseState(s) {
    switch (s) {
      case "":
        return Profile.CodeState.COMPILED;
      case "~":
        return Profile.CodeState.OPTIMIZABLE;
      case "*":
        return Profile.CodeState.OPTIMIZED;
    }
    throw new Error("unknown code state: " + s);
  }

  processCodeCreation(
    type, kind, timestamp, start, size, name, maybe_func) {
    if (maybe_func.length) {
      let funcAddr = parseInt(maybe_func[0]);
      let state = this.parseState(maybe_func[1]);
      this.profile_.addFuncCode(type, name, timestamp, start, size, funcAddr, state);
    } else {
      this.profile_.addCode(type, name, timestamp, start, size);
    }
  }

  processCodeMove(from, to) {
    this.profile_.moveCode(from, to);
  }

  processCodeDelete(start) {
    this.profile_.deleteCode(start);
  }

  processFunctionMove(from, to) {
    this.profile_.moveFunc(from, to);
  }

  formatPC(pc, line, column) {
    let entry = this.profile_.findEntry(pc);
    if (!entry) return "<unknown>"
    if (entry.type == "Builtin") {
      return entry.name;
    }
    let name = entry.func.getName();
    let re = /(.*):[0-9]+:[0-9]+$/;
    let array = re.exec(name);
    if (!array) {
      entry = name;
    } else {
      entry = entry.getState() + array[1];
    }
    return entry + ":" + line + ":" + column;
  }

  processMap(type, time, from, to, pc, line, column, reason, name) {
    time = parseInt(time);
    if (type == "Deprecate") return this.deprecateMap(type, time, from);
    from = this.getExistingMap(from, time);
    to = this.getExistingMap(to, time);
    let edge = new Edge(type, name, reason, time, from, to);
    to.filePosition = this.formatPC(pc, line, column);
    edge.finishSetup();
  }

  deprecateMap(type, time, id) {
    this.getExistingMap(id, time).deprecate();
  }

  processMapCreate(time, id, string) {
    // map-create events might override existing maps if the addresses get
    // rcycled. Hence we do not check for existing maps.
    let map = this.createMap(id, time);
    map.description = string;
  }

  processMapDetails(time, id, string) {
    //TODO(cbruni): fix initial map logging.
    let map = this.getExistingMap(id, time);
    if (!map.description) {
      map.description = string;
    }
  }

  createMap(id, time) {
    let map = new V8Map(id, time);
    this.timeline_.push(map);
    return map;
  }

  getExistingMap(id, time) {
    if (id === 0) return undefined;
    let map = V8Map.get(id);
    if (map === undefined) {
      console.error("No map details provided: id=" + id);
      // Manually patch in a map to continue running.
      return this.createMap(id, time);
    };
    return map;
  }
}

// ===========================================================================

class V8Map {
  constructor(id, time = -1) {
    if (!id) throw "Invalid ID";
    this.id = id;
    this.time = time;
    if (!(time > 0)) throw "Invalid time";
    this.description = "";
    this.edge = void 0;
    this.children = [];
    this.depth = 0;
    this._isDeprecated = false;
    this.deprecationTargets = null;
    V8Map.set(id, this);
    this.leftId = 0;
    this.rightId = 0;
    this.filePosition = "";
  }

  finalize(id) {
    // Initialize preorder tree traversal Ids for fast subtree inclusion checks
    if (id <= 0) throw "invalid id";
    let currentId = id;
    this.leftId = currentId
    this.children.forEach(edge => {
      let map = edge.to;
      currentId = map.finalize(currentId + 1);
    });
    this.rightId = currentId + 1;
    return currentId + 1;
  }

  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 + 0.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;
  }

  getType() {
    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) {
    if (!this.cache) return undefined;
    return this.cache.get(id);
  }

  static set(id, map) {
    if (!this.cache) this.cache = new Map();
    this.cache.set(id, 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() {
    if (this.from) this.from.addEdge(this);
    if (this.to) {
      this.to.edge = this;
      if (this.to === this.from) throw "From and to must be distinct.";
      if (this.from) {
        if (this.to.time < this.from.time) {
          console.error("invalid time order");
        }
        let newDepth = this.from.depth + 1;
        if (this.to.depth > 0 && this.to.depth != newDepth) {
          console.error("Depth has already been initialized");
        }
        this.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 : "")
  }
}


// ===========================================================================
class Marker {
  constructor(time, name) {
    this.time = parseInt(time);
    this.name = name;
  }
}

// ===========================================================================
class Timeline {
  constructor() {
    this.values = [];
    this.transitions = new Map();
    this.markers = [];
    this.startTime = 0;
    this.endTime = 0;
  }

  push(map) {
    let time = map.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, map);
    } else {
      this.values.push(map);
    }
    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);
      }
    }
  }

  addMarker(time, message) {
    this.markers.push(new Marker(time, message));
  }

  finalize() {
    let id = 0;
    this.forEach(map => {
      if (map.isRoot()) id = map.finalize(id + 1);
      if (map.edge && map.edge.name) {
        let edge = map.edge;
        let list = this.transitions.get(edge.name);
        if (list === undefined) {
          this.transitions.set(edge.name, [edge]);
        } else {
          list.push(edge);
        }
      }
    });
    this.markers.sort((a, b) => b.time - a.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 = [];
    let emptyMarkers = [];
    this.forEachChunkSize(count, (start, end, startTime, endTime) => {
      let items = this.values.slice(start, end);
      let markers = this.markersAt(startTime, endTime);
      chunks.push(new Chunk(chunks.length, startTime, endTime, items, markers));
    });
    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.basicFind(this.values, each => each.time - time, offset);
  }

  markersAt(startTime, endTime) {
    let start = this.basicFind(this.markers, each => each.time - startTime);
    let end = this.basicFind(this.markers, each => each.time - endTime, start);
    return this.markers.slice(start, end);
  }

  basicFind(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;
  }

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

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

  filterUniqueTransitions(filter) {
    // Returns a list of Maps whose parent is not in the list.
    return this.values.filter(map => {
      if (!filter(map)) return false;
      let parent = map.parent();
      if (!parent) return true;
      return !filter(parent);
    });
  }

  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, markers) {
    this.index = index;
    this.start = start;
    this.end = end;
    this.items = items;
    this.markers = markers
    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(map) {
    // items[0]   == oldest map, displayed at the top of the chunk
    // items[n-1] == youngest map, displayed at the bottom of the chunk
    return (1 - (this.indexOf(map) + 0.5) / this.size()) * this.height;
  }

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

  has(map) {
    if (this.isEmpty()) return false;
    return this.first().time <= map.time && map.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;
  }

  getTransitionBreakdown() {
    return BreakDown(this.items, map => map.getType())
  }

  getUniqueTransitions() {
    // Filter out all the maps that have parents within the same chunk.
    return this.items.filter(map => !map.parent() || !this.has(map.parent()));
  }
}


// ===========================================================================
function BreakDown(list, map_fn) {
  if (map_fn === void 0) {
    map_fn = each => each;
  }
  let breakdown = {__proto__:null};
  list.forEach(each=> {
    let type = map_fn(each);
    let v = breakdown[type];
    breakdown[type] = (v | 0) + 1
  });
  return Object.entries(breakdown)
    .sort((a,b) => a[1] - b[1]);
}


// ===========================================================================
class ArgumentsProcessor extends BaseArgumentsProcessor {
  getArgsDispatch() {
    return {
      '--range': ['range', 'auto,auto',
        'Specify the range limit as [start],[end]'
      ],
      '--source-map': ['sourceMap', null,
        'Specify the source map that should be used for output'
      ]
    };
  }

  getDefaultResults() {
    return {
      logFileName: 'v8.log',
      range: 'auto,auto',
    };
  }
}
