// This file is about the layout (Preproess() and Group()) of the IPMI time line view.
// The layout happens according to the following sequence that is very similar to how
// the layout is done for DBus messages:
//
// 1. User clicks any of the checkboxes for the grouping fields (NetFN, CMD)
// 2. OnGroupByConditionChanged() is called
// 3. OnGroupByConditionChanged() calls PreProcess() and Group()
// 4. PreProcess() takes the IPMI messages extracted from the DBus capture
//    (g_ipmi_parsed_entries), and determines the start time.
// 5. Group() takes the IPMI messages, and the list of keys, and groups the messages
//    by the keys. The output is picked up by GenerateTimeLine(), which writes the
//    timeline data into the Intervals and Titles arrays. The draw loop immediately
//    picks up the updated Intervals and Titles arrays and draws on the canvas
//    accordingly.

const {dialog} = require('electron').remote;
const {fs} = require('file-system');
const {util} = require('util');
const {exec} = require('child_process');

// Main view objects
var ipmi_timeline_view = new IPMITimelineView();
ipmi_timeline_view.IsTimeDistributionEnabled = true;

var btn_start_capture = document.getElementById('btn_start_capture');
var select_capture_mode = document.getElementById('select_capture_mode');
var capture_info = document.getElementById('capture_info');

var radio_open_file = document.getElementById('radio_open_file');
var radio_capture = document.getElementById('radio_capture');
var title_open_file = document.getElementById('title_open_file');
var title_capture = document.getElementById('title_capture');

// Set up Electron-related stuff here; Electron does not allow inlining button
// events
document.getElementById('c1').addEventListener(
    'click', OnGroupByConditionChanged);  // NetFN
document.getElementById('c2').addEventListener(
    'click', OnGroupByConditionChanged);  // CMD

// Zoom in button
document.getElementById('btn_zoom_in').addEventListener('click', function() {
  ipmi_timeline_view.BeginZoomAnimation(0.5);
  boost_asio_handler_timeline_view.BeginZoomAnimation(0.5);
});

// Zoom out button
document.getElementById('btn_zoom_out').addEventListener('click', function() {
  ipmi_timeline_view.BeginZoomAnimation(-1);
  boost_asio_handler_timeline_view.BeginZoomAnimation(-1);
});

// Pan left button
document.getElementById('btn_pan_left').addEventListener('click', function() {
  ipmi_timeline_view.BeginPanScreenAnimaton(-0.5);
  boost_asio_handler_timeline_view.BeginPanScreenAnimaton(-0.5);
});

// Pan right button
document.getElementById('btn_pan_right').addEventListener('click', function() {
  ipmi_timeline_view.BeginPanScreenAnimaton(0.5);
  boost_asio_handler_timeline_view.BeginPanScreenAnimaton(0.5);
});

// Reset zoom button
document.getElementById('btn_zoom_reset').addEventListener('click', function() {
  ipmi_timeline_view.BeginSetBoundaryAnimation(
      RANGE_LEFT_INIT, RANGE_RIGHT_INIT)
  dbus_timeline_view.BeginSetBoundaryAnimation(
      RANGE_LEFT_INIT, RANGE_RIGHT_INIT)
  boost_asio_handler_timeline_view.BeginSetBoundaryAnimation(
      RANGE_LEFT_INIT, RANGE_RIGHT_INIT)
})

// Generate replay
document.getElementById('gen_replay_ipmitool1')
    .addEventListener('click', function() {
      GenerateIPMIToolIndividualCommandReplay(HighlightedRequests);
    });
document.getElementById('gen_replay_ipmitool2')
    .addEventListener('click', function() {
      GenerateIPMIToolExecListReplay(HighlightedRequests);
    });
document.getElementById('gen_replay_ipmid_legacy')
    .addEventListener('click', function() {
      GenerateBusctlReplayLegacyInterface(HighlightedRequests);
    });
document.getElementById('gen_replay_ipmid_new')
    .addEventListener('click', function() {
      GenerateBusctlReplayNewInterface(HighlightedRequests);
    });
document.getElementById('btn_start_capture')
    .addEventListener('click', function() {
      let h = document.getElementById('text_hostname').value;
      g_capture_state = 'started';
      StartCapture(h);
    });

// For capture mode
document.getElementById('btn_stop_capture')
    .addEventListener('click', function() {
      StopCapture();
    });
document.getElementById('select_capture_mode')
    .addEventListener('click', OnCaptureModeChanged);
radio_open_file.addEventListener('click', OnAppModeChanged);
radio_capture.addEventListener('click', OnAppModeChanged);

radio_open_file.click();

// App mode: open file or capture
function OnAppModeChanged() {
  title_open_file.style.display = 'none';
  title_capture.style.display = 'none';
  if (radio_open_file.checked) {
    title_open_file.style.display = 'block';
  }
  if (radio_capture.checked) {
    title_capture.style.display = 'block';
  }
}

// Capture mode: Live capture or staged capture
function OnCaptureModeChanged() {
  let x = select_capture_mode;
  let i = capture_info;
  let desc = '';
  switch (x.value) {
    case 'live':
      desc = 'Live: read BMC\'s dbus-monitor console output directly';
      g_capture_mode = 'live';
      break;
    case 'staged':
      desc =
          'Staged, IPMI only: Store BMC\'s dbus-monitor output in a file and transfer back for display';
      g_capture_mode = 'staged';
      break;
    case 'staged2':
      desc =
          'Staged, DBus + IPMI: Store BMC\'s busctl output in a file and transfer back for display';
      g_capture_mode = 'staged2';
      break;
  }
  i.textContent = desc;
}

// Data
var HistoryHistogram = [];
// var Data_IPMI = []

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

let Intervals = [];
let Titles = [];
let HighlightedRequests = [];
let GroupBy = [];
let GroupByStr = '';

// (NetFn, Cmd) -> [ Bucket Indexes ]
// Normalized (0~1) bucket index for the currently highlighted IPMI requests
let IpmiVizHistHighlighted = {};
let HistogramThresholds = {};

function IsIntersected(i0, i1) {
  return (!((i0[1] < i1[0]) || (i0[0] > i1[1])));
}

function IsIntersectedPixelCoords(i0, i1) {
  if (i0[1] == undefined || isNaN(i0[1])) {
    return (Math.abs(i0[0] - i1[0]) < 5);
  } else {
    return (IsIntersected(i0, i1));
  }
}

var NetFnCmdToDescription = {
  '6, 1': 'App-GetDeviceId',
  '6, 3': 'App-WarmReset',
  '10, 64': 'Storage-GetSelInfo',
  '10, 35': 'Storage-GetSdr',
  '4, 32': 'Sensor-GetDeviceSDRInfo',
  '4, 34': 'Sensor-ReserveDeviceSDRRepo',
  '4, 47': 'Sensor-GetSensorType',
  '10, 34': 'Storage-ReserveSdrRepository',
  '46, 50': 'OEM Extension',
  '4, 39': 'Sensor-GetSensorThresholds',
  '4, 45': 'Sensor-GetSensorReading',
  '10, 67': 'Storage-GetSelEntry',
  '58, 196': 'IBM_OEM',
  '10, 32': 'Storage-GetSdrRepositoryInfo',
  '4, 33': 'Sensor-GetDeviceSDR',
  '6, 54': 'App-Get BT Interface Capabilities',
  '10, 17': 'Storage-ReadFruData',
  '10, 16': 'Storage-GetFruInventoryAreaInfo',
  '4, 2': 'Sensor-PlatformEvent',
  '4, 48': 'Sensor-SetSensor',
  '6, 34': 'App-ResetWatchdogTimer'
};

const CANVAS_H = document.getElementById('my_canvas_ipmi').height;
const CANVAS_W = document.getElementById('my_canvas_ipmi').width;

var LowerBoundTime = RANGE_LEFT_INIT;
var UpperBoundTime = RANGE_RIGHT_INIT;
var LastTimeLowerBound;
var LastTimeUpperBound;
// Dirty flags for determining when to redraw the canvas
let IsCanvasDirty = true;
let IsHighlightDirty = false;
// Animating left and right boundaries
let IsAnimating = false;
let LowerBoundTimeTarget = LowerBoundTime;
let UpperBoundTimeTarget = UpperBoundTime;
// For keyboard interaction: arrow keys and Shift
let CurrDeltaX = 0;         // Proportion of Canvas to scroll per frame.
let CurrDeltaZoom = 0;      // Delta zoom per frame.
let CurrShiftFlag = false;  // Whether the Shift key is depressed

// TODO: these variables are shared across all views but are now in ipmi_timeline_vis.js, need to move to some other location some time
const LEFT_MARGIN = 640
const RIGHT_MARGIN = 1390;
const LINE_HEIGHT = 15;
const LINE_SPACING = 17;
const YBEGIN = 22 + LINE_SPACING;
const TOP_HORIZONTAL_SCROLLBAR_HEIGHT = YBEGIN - LINE_HEIGHT / 2; // ybegin is the center of the 1st line of the text so need to minus line_height/2
const BOTTOM_HORIZONTAL_SCROLLBAR_HEIGHT = LINE_HEIGHT;
const TEXT_Y0 = 3;
const HISTOGRAM_W = 100, HISTOGRAM_H = LINE_SPACING;
const HISTOGRAM_X = 270;
// If some request's time is beyond the right tail, it's considered "too long"
// If some request's time is below the left tail it's considered "good"
// const HISTOGRAM_LEFT_TAIL_WIDTH = 0.05, HISTOGRAM_RIGHT_TAIL_WIDTH = 0.05;
// temporarily disabled for now
const HISTOGRAM_LEFT_TAIL_WIDTH = -1, HISTOGRAM_RIGHT_TAIL_WIDTH = -1;
const SCROLL_BAR_WIDTH = 16;

let IpmiVizHistogramImageData = {};  // Image data for rendered histogram

// Input is the data that's completed layout
// is_free_x:     Should each histogram has its own X range or not
// num_buckets: # of buckets for histograms
// theta: top and bottom portion to cut
function ComputeHistogram(num_buckets = 30, is_free_x = true) {
  let global_lb = Infinity, global_ub = -Infinity;
  IpmiVizHistogramImageData = {};
  // Global minimal and maximal values
  for (let i = 0; i < Intervals.length; i++) {
    let interval = Intervals[i];
    let l = Math.min.apply(Math, interval.map(function(x) {
      return x[1] - x[0];
    }));
    let u = Math.max.apply(Math, interval.map(function(x) {
      return x[1] - x[0];
    }));
    global_lb = Math.min(l, global_lb);
    global_ub = Math.max(u, global_ub);
  }

  HistoryHistogram = [];
  for (let i = 0; i < Intervals.length; i++) {
    let interval = Intervals[i];
    let lb = global_lb, ub = global_ub;
    if (is_free_x == true) {
      lb = Math.min.apply(Math, interval.map(function(x) {
        return x[1] - x[0];
      }));
      ub = Math.max.apply(Math, interval.map(function(x) {
        return x[1] - x[0];
      }));
    }
    const EPS = 1e-2;
    if (lb == ub) ub = lb + EPS;
    let line = [lb * 1000000, ub * 1000000];  // to usec
    let buckets = [];
    for (let j = 0; j < num_buckets; j++) buckets.push(0);
    for (let j = 0; j < interval.length; j++) {
      let t = interval[j][1] - interval[j][0];
      let bucket_idx = parseInt(t / ((ub - lb) / num_buckets));
      buckets[bucket_idx]++;
    }
    line.push(buckets);
    HistoryHistogram[Titles[i].title] = line;
  }
}

function Preprocess(data) {
  preprocessed = [];
  let StartingUsec_IPMI;

  if (g_StartingSec == undefined) {
    StartingUsec_IPMI = undefined;
  } else {
    StartingUsec_IPMI = g_StartingSec * 1000000;
  }

  for (let i = 0; i < data.length; i++) {
    let entry = data[i].slice();
    let lb = entry[2], ub = entry[3];

    // Only when IPMI view is present (i.e. no DBus pcap is loaded)
    if (i == 0 && StartingUsec_IPMI == undefined) {
      StartingUsec_IPMI = lb;
    }

    entry[2] = lb - StartingUsec_IPMI;
    entry[3] = ub - StartingUsec_IPMI;
    preprocessed.push(entry);
  }
  return preprocessed;
}

let SHOW_BLOB_DETAILS = true;
function Group(data, groupBy) {
  let grouped = {};

  // If has netfn and cmd: use "NetFN, CMD" as key
  // Otherwise, use "NetFN" as key
  // This distinction is made if the user chooses to label operation on each
  // blob individually

  // Key:   blob name
  // Value: the commands that operate on the particular blob
  let sid2blobid = {}

  for (let n = 0; n < data.length; n++) {
    const p = data[n];
    const netfn = p[0], cmd = p[1], req = p[4], res = p[5];
    if (netfn == 46 && cmd == 128) {
      const oen = req[0] + req[1] * 256 + req[2] * 65536;
      if (oen == 0xc2cf) {  // Blob operations
        const blobcmd =
            req[3];  // Refer to https://github.com/openbmc/phosphor-ipmi-blobs

        // The IPMI blob commands are visible on DBus, another WIP command-line tool that
        // utilizes this fact to show information about blobs can be found here:
        // https://gerrit.openbmc-project.xyz/c/openbmc/openbmc-tools/+/41451

        let sid, blobid;

        // layout of req
        //  0  1  2   3  4  5   6  7  8  9  10 ...
        // CF C2 00 CMD [CRC ] [ other stuff  ]

        // layout of res
        //  0  1  2   3  4   5   6  7  8  ...
        // CF C2 00  [CRC ] [other stuff]

        // Determining blob id and session ID
        switch (blobcmd) {
          case 3:
          case 4:
          case 5:
          case 6:
          case 9:
          case 10: {
            const sid = req[6] + req[7] * 256;
            blobid = sid2blobid[sid];
            if (blobid != undefined) {
              p.key = blobid;
            }
            break;
          }
          case 7:
          case 8: {
            blobid = '';
            for (let i = 6; i < req.length; i++) {
              blobid += String.fromCharCode(req[i]);
            }
            break;
          }
        }

        switch (blobcmd) {
          case 2: {  // open
            blobid = '';
            for (let i = 8; i < req.length; i++) {
              if (req[i] == 0)
                break;
              else
                blobid += String.fromCharCode(req[i]);
            }
            p.key = blobid;
            sid = res[5] + res[6] * 256;  // session_id
            sid2blobid[sid] = blobid;
            break;
          }
          case 3: {  // Read

            break;
          }
          case 4: {  // Write
            const offset =
                req[8] + req[9] * 256 + req[10] * 65536 + req[11] * 16777216;
            p.offset = offset;
            break;
          }
          case 5: {  // Commit
            break;
          }
          case 6: {  // Close
            break;
          }
        }
      }
    }
  }

  const idxes = {'NetFN': 0, 'CMD': 1};

  //
  for (let n = 0; n < data.length; n++) {
    const p = data[n];
    let key = '';
    if (p.key != undefined)
      key = p.key;
    else if (p[0] != '' && p[1] != '') {
      for (let i = 0; i < groupBy.length; i++) {
        if (i > 0) {
          key += ', ';
        }
        key += p[idxes[groupBy[i]]];
      }
    }

    if (grouped[key] == undefined) {
      grouped[key] = [];
    }
    grouped[key].push(p);
  }

  return grouped;
}

function GenerateTimeLine(grouped) {
  const keys = Object.keys(grouped);
  let sortedKeys = keys.slice();
  // If NetFN and CMD are both selected, sort by NetFN then CMD
  // In this case, all "keys" are string-encoded integer pairs
  if (keys.length > 0 && ipmi_timeline_view.GroupBy.length == 2) {
    sortedKeys = sortedKeys.sort(function(a, b) {
      a = a.split(',');
      b = b.split(',');
      if (a.length == 2 && b.length == 2) {
        let aa = parseInt(a[0]) * 256 + parseInt(a[1]);
        let bb = parseInt(b[0]) * 256 + parseInt(b[1]);
        return aa < bb ? -1 : (aa > bb ? 1 : 0);
      } else {
        return a < b ? -1 : (a > b ? 1 : 0);
      }
    });
  }

  Intervals = [];
  Titles = [];
  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];
      // Lower bound, Upper bound, and a reference to the original request
      line.push([
        parseFloat(entry[2]) / 1000000, parseFloat(entry[3]) / 1000000, entry,
        'ok', 0
      ]);
    }
    Intervals.push(line);
  }

  ipmi_timeline_view.Intervals = Intervals.slice();
  ipmi_timeline_view.Titles = Titles.slice();
  ipmi_timeline_view.LayoutForOverlappingIntervals();
}

function OnGroupByConditionChanged() {
  const tags = ['c1', 'c2'];
  const v = ipmi_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 = Preprocess(Data_IPMI);
  grouped = Group(preproc, v.GroupBy);
  GenerateTimeLine(grouped);

  IsCanvasDirty = true;
  ipmi_timeline_view.IsCanvasDirty = true;
}

function MapXCoord(x, left_margin, right_margin, rl, rr) {
  let ret = left_margin + (x - rl) / (rr - rl) * (right_margin - left_margin);
  if (ret < left_margin) {
    ret = left_margin;
  } else if (ret > right_margin) {
    ret = right_margin;
  }
  return ret;
}

function draw_timeline(ctx) {
  ipmi_timeline_view.Render(ctx);
}


window.addEventListener('keydown', function() {
  if (event.keyCode == 37) {  // Left Arrow
    ipmi_timeline_view.CurrDeltaX = -0.004;
    dbus_timeline_view.CurrDeltaX = -0.004;
  } else if (event.keyCode == 39) {  // Right arrow
    ipmi_timeline_view.CurrDeltaX = 0.004;
    dbus_timeline_view.CurrDeltaX = 0.004;
  } else if (event.keyCode == 16) {  // Shift
    ipmi_timeline_view.CurrShiftFlag = true;
    dbus_timeline_view.CurrShiftFlag = true;
  } else if (event.keyCode == 38) {  // Up arrow
    ipmi_timeline_view.CurrDeltaZoom = 0.01;
    dbus_timeline_view.CurrDeltaZoom = 0.01;
  } else if (event.keyCode == 40) {  // Down arrow
    ipmi_timeline_view.CurrDeltaZoom = -0.01;
    dbus_timeline_view.CurrDeltaZoom = -0.01;
  }
});

window.addEventListener('keyup', function() {
  if (event.keyCode == 37 || event.keyCode == 39) {
    ipmi_timeline_view.CurrDeltaX = 0;
    dbus_timeline_view.CurrDeltaX = 0;
  } else if (event.keyCode == 16) {
    ipmi_timeline_view.CurrShiftFlag = false;
    dbus_timeline_view.CurrShiftFlag = false;
  } else if (event.keyCode == 38 || event.keyCode == 40) {
    ipmi_timeline_view.CurrDeltaZoom = 0;
    dbus_timeline_view.CurrDeltaZoom = 0;
  }
});

function MouseXToTimestamp(x) {
  let ret = (x - LEFT_MARGIN) / (RIGHT_MARGIN - LEFT_MARGIN) *
          (UpperBoundTime - LowerBoundTime) +
      LowerBoundTime;
  ret = Math.max(ret, LowerBoundTime);
  ret = Math.min(ret, UpperBoundTime);
  return ret;
}

let HighlightedRegion = {t0: -999, t1: -999};

function IsHighlighted() {
  return (HighlightedRegion.t0 != -999 && HighlightedRegion.t1 != -999);
}

function Unhighlight() {
  HighlightedRegion.t0 = -999;
  HighlightedRegion.t1 = -999;
}

function UnhighlightIfEmpty() {
  if (HighlightedRegion.t0 == HighlightedRegion.t1) {
    Unhighlight();
    return true;
  }
  return false;
}

let MouseState = {
  hovered: true,
  pressed: false,
  x: 0,
  y: 0,
  hoveredVisibleLineIndex: -999,
  hoveredSide: undefined,
  IsHoveredOverHorizontalScrollbar: function() {
    if (this.hoveredSide == "top_horizontal_scrollbar") return true;
    else if (this.hoveredSide == "bottom_horizontal_scrollbar") return true;
    else return false;
  }
};
let Canvas = document.getElementById('my_canvas_ipmi');

Canvas.onmousemove = function(event) {
  const v = ipmi_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.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.onmouseover = function() {
  ipmi_timeline_view.OnMouseMove();
};

Canvas.onmouseleave = function() {
  ipmi_timeline_view.OnMouseLeave();
};

Canvas.onmousedown = function(event) {
  if (event.button == 0) {  // Left mouse button
    ipmi_timeline_view.OnMouseDown();
  }
};

Canvas.onmouseup = function(event) {
  if (event.button == 0) {
    ipmi_timeline_view.OnMouseUp();
    // page-specific, not view-specific
    let hint = document.getElementById('highlight_hint');
    if (ipmi_timeline_view.UnhighlightIfEmpty()) {
      hint.style.display = 'none';
    } else {
      hint.style.display = 'block';
    }
  }
};

Canvas.onwheel = function(event) {
  ipmi_timeline_view.OnMouseWheel(event);
};

// This function is not specific to TimelineView so putting it here
function OnHighlightedChanged(reqs) {
  let x = document.getElementById('ipmi_replay');
  let i = document.getElementById('ipmi_replay_output');
  let cnt = document.getElementById('highlight_count');
  cnt.innerHTML = '' + reqs.length;
  i.style.display = 'none';
  if (reqs.length > 0) {
    x.style.display = 'block';
  } else
    x.style.display = 'none';
  let o = document.getElementById('ipmi_replay_output');
  o.style.display = 'none';
  o.textContent = '';
}

function ToHexString(bytes, prefix, sep) {
  let ret = '';
  for (let i = 0; i < bytes.length; i++) {
    if (i > 0) {
      ret += sep;
    }
    ret += prefix + bytes[i].toString(16);
  }
  return ret;
}

function ToASCIIString(bytes) {
  ret = '';
  for (let i = 0; i < bytes.length; i++) {
    ret = ret + String.fromCharCode(bytes[i]);
  }
  return ret;
}

function ShowReplayOutputs(x, ncols) {
  let o = document.getElementById('ipmi_replay_output');
  o.cols = ncols;
  o.style.display = 'block';
  o.textContent = x;
}

function GenerateIPMIToolIndividualCommandReplay(reqs) {
  let x = '';
  for (let i = 0; i < reqs.length; i++) {
    let req = reqs[i];
    // [0]: NetFN, [1]: cmd, [4]: payload
    // NetFN and cmd are DECIMAL while payload is HEXADECIMAL.
    x = x + 'ipmitool raw ' + req[0] + ' ' + req[1] + ' ' +
        ToHexString(req[4], '0x', ' ') + '\n';
  }
  ShowReplayOutputs(x, 80);
}

function GenerateIPMIToolExecListReplay(reqs) {
  console.log(reqs.length);
  let x = '';
  for (let i = 0; i < reqs.length; i++) {
    let req = reqs[i];
    x = x + 'raw ' +
        ToHexString([req[0]].concat([req[1]]).concat(req[4]), '0x', ' ') + '\n';
  }
  ShowReplayOutputs(x, 80);
}

function GenerateBusctlReplayLegacyInterface(reqs) {
  console.log(reqs.length);
  let serial = 0;
  let x = '';
  for (let i = 0; i < reqs.length; i++) {
    let req = reqs[i];
    x = x +
        'busctl --system emit  /org/openbmc/HostIpmi/1 org.openbmc.HostIpmi ReceivedMessage yyyyay ';
    x = x + serial + ' ' + req[0] + ' 0 ' + req[1] + ' ' + req[4].length + ' ' +
        ToHexString(req[4], '0x', ' ') + '\n';
    serial = (serial + 1) % 256;
  }
  ShowReplayOutputs(x, 120);
}

function GenerateBusctlReplayNewInterface(reqs) {
  console.log(reqs.length);
  let x = '';
  for (let i = 0; i < reqs.length; i++) {
    let req = reqs[i];
    x = x +
        'busctl --system call xyz.openbmc_project.Ipmi.Host /xyz/openbmc_project/Ipmi xyz.openbmc_project.Ipmi.Server execute yyyaya{sv} ';
    x = x + req[0] + ' 0 ' + req[1] + ' ' + req[4].length + ' ' +
        ToHexString(req[4], '0x', ' ');
    +' 0\n';
  }
  ShowReplayOutputs(x, 150);
}
