// This script deals with Boost ASIO handlers
// Will need to add code to visualize one-shot events

// Fields: HandlerNumber, Level,
// Creation time, Enter time, Exit time, EnterDescription,
//    [ [Operation, time] ]

// Will use g_StartingSec as the starting of epoch

var ASIO_Data = [];
var ASIO_Timestamp = [];

function FindFirstEntrySlot(slots) {
  let i = 0;
  for (; i < slots.length; i++) {
    if (slots[i] == undefined) break;
  }
  if (i >= slots.length) slots.push(undefined);
  return i;
}

function SimplifyDesc(desc) {
  const idx0 = desc.indexOf('0x');
  if (idx0 == -1)
    return desc;
  else {
    const d1 = desc.substr(idx0 + 2);
    let idx1 = 0;
    while (idx1 + 1 < d1.length &&
           ((d1[idx1] >= '0' && d1[idx1] <= '9') ||
            (d1[idx1] >= 'A' && d1[idx1] <= 'F') ||
            (d1[idx1] >= 'a' && d1[idx1] <= 'f'))) {
      idx1++;
    }
    return desc.substr(0, idx0) + d1.substr(idx1)
  }
}

function ParseBoostHandlerTimeline(content) {
  let parsed_entries = [];
  const lines = content.split('\n');
  let slots = [];               // In-flight handlers
  let in_flight_id2level = {};  // In-flight ID to level

  for (let lidx = 0; lidx < lines.length; lidx++) {
    const line = lines[lidx];
    if (line.startsWith('@asio|') == false) continue;
    const sp = line.split('|');

    const tag = sp[0], ts = sp[1], action = sp[2], desc = sp[3];
    let handler_id = -999;
    let ts_sec = parseFloat(ts);
    const simp_desc = SimplifyDesc(desc);

    if (action.indexOf('*') != -1) {
      const idx = action.indexOf('*');
      const handler_id = parseInt(action.substr(idx + 1));
      const level = FindFirstEntrySlot(slots);

      // Create an entry here
      let entry = [
        handler_id, level, ts_sec, undefined, undefined, desc, simp_desc, []
      ];

      slots[level] = entry;
      in_flight_id2level[handler_id] = level;
    } else if (action[0] == '>') {  // The program enters handler number X
      handler_id = parseInt(action.substr(1));
      if (handler_id in in_flight_id2level) {
        const level = in_flight_id2level[handler_id];
        let entry = slots[level];
        entry[3] = ts_sec;
      }
    } else if (action[0] == '<') {
      handler_id = parseInt(action.substr(1));
      if (handler_id in in_flight_id2level) {
        const level = in_flight_id2level[handler_id];
        let entry = slots[level];
        entry[4] = ts_sec;
        slots[level] = undefined;
        parsed_entries.push(entry);
        delete in_flight_id2level[handler_id];
      }
    } else if (action[0] == '.') {  // syscalls
    }
  }

  console.log(
      'Boost handler log: ' + parsed_entries.length + ' entries' +
      ', ' + slots.length + ' levels');
  ASIO_Data = parsed_entries;
  return parsed_entries;
}

function Group_ASIO(preprocessed, group_by) {
  let grouped = {};
  const IDXES = {'Layout Level': 1, 'Description': 5, 'Description1': 6};
  for (var n = 0; n < preprocessed.length; n++) {
    var key = ''
    for (var i = 0; i < group_by.length; i++) {
      if (i > 0) key += ' ';
      key += ('' + preprocessed[n][IDXES[group_by[i]]]);
    }
    if (grouped[key] == undefined) grouped[key] = [];
    grouped[key].push(preprocessed[n]);
  }
  return grouped;
}

function OnGroupByConditionChanged_ASIO() {
  var tags = ['bah1', 'bah2', 'bah3'];
  const v = boost_asio_handler_timeline_view;
  v.GroupBy = [];
  v.GroupByStr = '';
  for (let i = 0; i < tags.length; i++) {
    let cb = document.getElementById(tags[i]);
    if (cb.checked) {
      v.GroupBy.push(cb.value);
      if (v.GroupByStr.length > 0) {
        v.GroupByStr += ', ';
      }
      v.GroupByStr += cb.value;
    }
  }
  let preproc = ASIO_Data;
  let grouped = Group_ASIO(preproc, v.GroupBy);
  GenerateTimeLine_ASIO(grouped);
  boost_asio_handler_timeline_view.IsCanvasDirty = true;
}

function GenerateTimeLine_ASIO(grouped) {
  const keys = Object.keys(grouped);
  let sortedKeys = keys.slice();
  let intervals = [];
  let titles = [];

  const was_starting_time_undefined = (g_StartingSec == undefined);

  for (let i = 0; i < sortedKeys.length; i++) {
    titles.push({"header":false, "title":sortedKeys[i], "intervals_idxes":[i] });
    line = [];
    for (let j = 0; j < grouped[sortedKeys[i]].length; j++) {
      let entry = grouped[sortedKeys[i]][j];
      let t0 = parseFloat(entry[3]);
      let t1 = parseFloat(entry[4]);

      if (was_starting_time_undefined) {
        if (g_StartingSec == undefined) {
          g_StartingSec = t0;
        }
        g_StartingSec = Math.min(g_StartingSec, t0);
      }

      line.push([t0, t1, entry, 'ok', 0]);
    }
    intervals.push(line);
  }

  // Time shift
  for (let i = 0; i < intervals.length; i++) {
    for (let j = 0; j < intervals[i].length; j++) {
      let x = intervals[i][j];
      x[0] -= g_StartingSec;
      x[1] -= g_StartingSec;
    }
  }

  boost_asio_handler_timeline_view.Intervals = intervals.slice();
  boost_asio_handler_timeline_view.Titles = titles.slice();
  boost_asio_handler_timeline_view.LayoutForOverlappingIntervals();
}

// Main view object for Boost handler timeline

boost_asio_handler_timeline_view = new BoostASIOHandlerTimelineView();
boost_asio_handler_timeline_view.IsCanvasDirty = true;

function draw_timeline_boost_asio_handler(ctx) {
  boost_asio_handler_timeline_view.Render(ctx);
}

let Canvas_Asio = document.getElementById('my_canvas_boost_asio_handler');

Canvas_Asio.onmousemove = function(event) {
  const v = boost_asio_handler_timeline_view;
  v.MouseState.x = event.pageX - this.offsetLeft;
  v.MouseState.y = event.pageY - this.offsetTop;
  if (v.MouseState.pressed == true &&
      v.MouseState.hoveredSide == 'timeline') {  // Update highlighted area
    v.HighlightedRegion.t1 = v.MouseXToTimestamp(v.MouseState.x);
  }
  v.OnMouseMove();
  v.IsCanvasDirty = true;

  v.linked_views.forEach(function(u) {
    u.MouseState.x = event.pageX - Canvas_Asio.offsetLeft;
    u.MouseState.y = 0;                  // Do not highlight any entry
    if (u.MouseState.pressed == true &&
        u.MouseState.hoveredSide == 'timeline') {  // Update highlighted area
      u.HighlightedRegion.t1 = u.MouseXToTimestamp(u.MouseState.x);
    }
    u.OnMouseMove();
    u.IsCanvasDirty = true;
  });
};

Canvas_Asio.onmousedown = function(event) {
  if (event.button == 0) {
    boost_asio_handler_timeline_view.OnMouseDown();
  }
};

Canvas_Asio.onmouseup = function(event) {
  if (event.button == 0) {
    boost_asio_handler_timeline_view.OnMouseUp();
  }
};

Canvas_Asio.onwheel = function(event) {
  boost_asio_handler_timeline_view.OnMouseWheel(event);
}
