// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Class to handle file actions and trigger log processing.  After
 * logs are processed, summary information is displayed in the document.
 */
'use strict';

document.addEventListener('DOMContentLoaded', function() {
  var docNode = document.getElementById('file_name');
  if (docNode) {
    docNode.addEventListener('change', parseFile);
  } else {
    console.log('Cannot add event listener, must be testing.');
  }
});

/**
 * Method to get the file name and trigger the file read.
 *
 * @private
 */
function parseFile() {
  var logFile = document.getElementById('file_name').files;
  if (logFile[0]) {
    console.log('got the file!: ' + logFile[0].name);
    readFile(logFile[0]);
  } else {
    console.log('file selection cancelled.');
  }
}

/**
 * Method to open the selected file and break into a String[] for processing.
 *
 * @param {String} logFile Name of the file to open.
 * @private
 */
function readFile(logFile) {
  var logSummary = new LogSummary();
  // clean up old log output
  cleanupForNewFile();
  var fileReader = new FileReader();
  fileReader.onloadend = function(processEvent) {
    if (processEvent.target.readyState == FileReader.DONE) {
      var logLines = this.result.split('\n');
      var logHolder = logHelper.detectFileType(logLines);
      console.log('detected file type: ' + logHolder.fileType);
      var logText;
      if (logHolder.fileType == 'unknown') {
        displayError();
        logLines = null;
        return;
      }

      if (logHolder.androidlog) {
        logHolder.androidlog = androidlogSummary.processLogLines(
            logHolder.androidlog, logSummary);
      }

      if (logHolder.brillolog) {
        logHolder.brillolog = netlogSummary.processLogLines(logHolder.brillolog,
                                                            logSummary);
      }

      if (logHolder.netlog) {
        console.log('processing netlog');
        logHolder.netlog = netlogSummary.processLogLines(logHolder.netlog,
                                                         logSummary);
      }
      if (logHolder.syslog) {
        console.log('processing syslog');
        logHolder.syslog = syslogSummary.processLogLines(logHolder.syslog,
                                                         logSummary);
      }

      if (logHolder.netlog || logHolder.brillolog) {
        displayLogSummary(logSummary);
        displayServiceSummary(logSummary);
      }
      if (logHolder.androidlog) {
        displayAndroidLogSummary(logSummary);
      }

      if (logHolder.syslog || logHolder.netlog ||
          logHolder.brillolog || logHolder.androidlog) {
        displayLog(logHolder);
      } else {
        displayError();
      }

      logLines = null;
      logText = null;
    }
  };
  fileReader.readAsText(logFile);
}

/**
 * Method to clean up state between selected files.
 *
 * @private
 */
function cleanupForNewFile() {
  var oldManager = document.getElementsByClassName('managers');
  while (oldManager[0].hasChildNodes()) {
    oldManager[0].removeChild(oldManager[0].lastChild);
  }
}

/**
 * Method to display log-level summary information after processing the
 * Android log.
 *
 * @param {LogSummary} logSummary Object to hold state read from log.
 * @private
 */
function displayAndroidLogSummary(logSummary) {
  console.log('inside android log summary!');
  var wsm = document.getElementsByClassName('managers')[0];
  var logHeader = document.createElement('h2');
  logHeader.innerText = 'Log Summary';
  wsm.appendChild(logHeader);

  var timeInfo = document.createElement('p');
  timeInfo.innerText = 'Total Log Time: ' +
      logHelper.formatElapsedMS(logSummary.logEndTime -
                                logSummary.logStartTime);
  wsm.appendChild(timeInfo);

  var wifiStateMachines = logSummary.wifiStateMachines;
  var wsmInfo;
  for (var i = 0; i < wifiStateMachines.length; i++) {
    var stateMachine = logSummary.wifiStateMachines[i];
    wsmInfo = document.createElement('p');
    wsmInfo.innerText = 'WifiStateMachine ' + stateMachine.id + ': ' +
         logHelper.formatElapsedMS(stateMachine.endTime -
                                   stateMachine.startTime);
    wsm.appendChild(wsmInfo);

    // post processing for WSM states before graphing
    var xTime;
    var graphData = stateMachine.networkDetailedStates;
    for (var j = 0; j < graphData.length; j++) {
      if (graphData[j].x != 0) {
        xTime = Date.parse(graphData[j].x) - stateMachine.startTime;
      } else {
        xTime = 0;
      }
      graphData[j].x = xTime;
    }
    if (graphData.length > 0) {
      graphData.push({'x': stateMachine.endTime - stateMachine.startTime,
                      'y': graphData[graphData.length - 1].y});
    }
    console.log('wifiSM check: ', stateMachine);

    // post processing for supplicant states before graphing
    var suppStates = stateMachine.supplicantStates;
    if (suppStates.length > 0) {
      var lastState = suppStates[suppStates.length - 1];
      suppStates.push({'x': stateMachine.endTime - stateMachine.startTime,
                       'y': lastState.y});
    }
    console.log('supplicantData check: ', stateMachine.supplicantStates);

    androidStateGraph.createGraph(wsm, stateMachine);
  }

  //Now add in notes for the WSM
  var wsmHeader = document.createElement('h2');
  wsmHeader.innerText = 'WifiStateMachines';
  wsm.appendChild(wsmHeader);

  var wsmOL = document.createElement('ol');
  var wifiStateMachineNotes;
  for (var i = 0; i < wifiStateMachines.length; i++) {
    wifiStateMachineNotes = document.createElement('li');
    wifiStateMachineNotes.id = 'wsm_' + i;
    wifiStateMachineNotes.innerText = 'WifiStateMachine ' +
        wifiStateMachines[i].id;
    wifiStateMachineNotes.className = 'wsm';
    if (wifiStateMachines[i].notes && wifiStateMachines[i].notes.length > 0) {
      wifiStateMachineNotes.appendChild(
          displayNotes(logSummary, wifiStateMachines[i].notes));
    }
    wsmOL.appendChild(wifiStateMachineNotes);
  }
  wsm.appendChild(wsmOL);
}

/**
 * Method to display log-level summary information after processing the log.
 *
 * @param {LogSummary} logSummary Object to hold state read from log.
 * @private
 */
function displayLogSummary(logSummary) {
  console.log('inside log summary!');
  var manager = document.getElementsByClassName('managers');
  var logHeader = document.createElement('h2');
  var summaryLink = document.createElement('a');
  summaryLink.href = '#';
  summaryLink.innerText = 'Log Summary';
  summaryLink.addEventListener('click', function(event) {
    event.preventDefault();
    this.classList.toggle('active');
    var content = document.getElementById('summary');
    if (content.style.display === 'block') {
      content.style.display = 'none';
    } else {
      content.style.display = 'block';
    }
  });
  logHeader.appendChild(summaryLink);
  manager[0].appendChild(logHeader);
  var summary = document.createElement('div');
  summary.id = 'summary';
  summary.style.display = 'block';
  var timeInfo = document.createElement('p');
  timeInfo.innerText = 'Total Log Time: ' +
      logHelper.formatElapsedMS(
          logSummary.logEndTime - logSummary.logStartTime);
  summary.appendChild(timeInfo);
  manager[0].appendChild(summary);
  var activeServiceLabel = 'Active Service ';
  var managers = logSummary.managers;
  for (var i = 0; i < managers.length; i++) {
    var mInfo = document.createElement('p');
    mInfo.innerText = 'Manager ' + managers[i].id + ' ' +
        logHelper.formatElapsedMS(managers[i].endTime - managers[i].startTime);

    if (managers[i].connFromSuspend.length > 0) {
      var suspendConnInfo = document.createElement('p');
      var suspendConnTimes = managers[i].connFromSuspend;
      suspendConnInfo.innerText = 'suspendDone to Online:';
      for (var w = 0; w < suspendConnTimes.length; w++) {
        if (suspendConnTimes[w].suspendDone && suspendConnTimes[w].conn) {
          var t = logHelper.formatElapsedMS(
              suspendConnTimes[w].conn - suspendConnTimes[w].suspendDone);
          suspendConnInfo.innerText += '  [' + t + ']  ';
        }
        else if (suspendConnTimes[w].suspendDone) {
          suspendConnInfo.innerText += '  [NA_]  ';
        } else {
          suspendConnInfo.innerText += '  [_NA]  ';
        }
      }
      mInfo.appendChild(suspendConnInfo);
    }

    var activeService = '';
    var failures;
    for (var j = 0; j < managers[i].services.length; j++) {
      failures = '';
      if (managers[i].services[j].isActive) {
        for (var z = 0; z < managers[i].services[j].states.length; z++) {
          if (z > 0) {
            activeService += '--> ';
          }
          activeService += managers[i].services[j].states[z].state + ' ';
          if (managers[i].services[j].states[z].state == 'Failure') {
            var temp = managers[i].services[j].states[z];
            failures += ' [' + temp.failure + ']';
          }
        }
        var stateInfo = document.createElement('p');
        stateInfo.innerText = activeServiceLabel +
            managers[i].services[j].serviceId + ': ' + activeService;

        var connCountInfo = document.createElement('p');
        connCountInfo.innerText = 'Connections: ' +
            managers[i].services[j].connections;
        stateInfo.appendChild(connCountInfo);
        activeService = '';

        if (managers[i].services[j].connections > 0) {
          var connTimeInfo = document.createElement('p');
          var connTimes = managers[i].services[j].connectionTimes;
          connTimeInfo.innerText = 'Time to Connect [assoc to ' +
                                   'online or failure (O|F)]:';
          for (var w = 0; w < connTimes.length; w++) {
            if (connTimes[w].start && connTimes[w].end) {
              var t = logHelper.formatElapsedMS(
                  connTimes[w].end - connTimes[w].start);
              connTimeInfo.innerText +=
                  '  [' + t + ' (' + connTimes[w].type + ')]  ';
            }
            else if (connTimes[w].start) {
              connTimeInfo.innerText +=
                  '  [NA_ (' + connTimes[w].type + ')]  ';
            } else {
              connTimeInfo.innerText += '  [_NA]  ';
            }
          }
          stateInfo.appendChild(connTimeInfo);
        }

        if (failures != '') {
          var failureInfo = document.createElement('p');
          failureInfo.innerText = 'Failures: ' + failures;
          stateInfo.appendChild(failureInfo);
        }

        console.log('graphData check: ', managers[i].services[j].graphData);
        var xTime;
        var graphData = managers[i].services[j].graphData;
        for (var z = 0; z < graphData.length; z++) {
          if (graphData[z].x != 0) {
            xTime = Date.parse(graphData[z].x) - managers[i].startTime;
          } else {
            xTime = 0;
          }
          graphData[z].x = xTime;
          if (z + 1 == graphData.length) {
            graphData.push({'x': managers[i].endTime - managers[i].startTime,
                            'y': graphData[z].y});
            z = z + 2;
          }
        }

        mInfo.appendChild(stateInfo);
      }
    }
    console.log('scanDetail check: ', managers[i].scanDetails);

    console.log('suspendDetail check: ', managers[i].suspendDetails);
    var suspendCount = managers[i].suspendDetails.length;
    if (suspendCount > 0) {
      // double check first and last suspend entries
      var suspendEntry = managers[i].suspendDetails[0];
      if (suspendEntry.start == null) {
        suspendEntry.start = 0;
      }
      suspendEntry = managers[i].suspendDetails[suspendCount - 1];
      if (suspendEntry.end == null) {
        suspendEntry.end = managers[i].endTime - managers[i].startTime;
      }
    }

    for (var x = 0; x < managers[i].suspendDetails.length; x++) {
      var checkDarkSuspends = managers[i].suspendDetails[x].darkSuspends;
      if (checkDarkSuspends) {
        console.log('darkSuspendCheck: ', checkDarkSuspends);
        for (var y = 0; y < checkDarkSuspends.length; y++) {
          if (checkDarkSuspends[y].start == null) {
            checkDarkSuspends[y].start = managers[i].suspendDetails[x].start;
          }
          if (checkDarkSuspends[y].end == null) {
            checkDarkSuspends[y].end = managers[i].suspendDetails[x].end;
          }
        }
        console.log('fixed darkSuspendCheck: ', checkDarkSuspends);
      }
    }
    var suppStates = managers[i].supplicantStates;
    if (suppStates.length > 0) {
      var lastState = suppStates[suppStates.length - 1];
      suppStates.push({'x': managers[i].endTime - managers[i].startTime,
                                                'y': lastState.y});
    }
    console.log('supplicantData check: ', managers[i].supplicantStates);

    console.log('manager notes check: ', managers[i].notes);

    stateGraph.createGraph(summary, managers[i]);

    summary.appendChild(mInfo);
  }
}

/**
 * Method to display an error message for a file that could not be processed.
 *
 * @private
 */
function displayError() {
  var manager = document.getElementsByClassName('managers');
  var errorHeader = document.createElement('h2');
  errorHeader.innerText = 'File format not recognized.';
  manager[0].appendChild(errorHeader);
}

/**
 * Method to display individual service summaries with active states after
 * processing a netlog.
 *
 * @param {LogSummary} logSummary Object holding state from processing the log.
 * @private
 */
function displayServiceSummary(logSummary) {
  var managers = logSummary.managers;
  var manager = document.getElementsByClassName('managers');
  var managerHeader = document.createElement('h2');
  var managerLink = document.createElement('a');
  managerLink.href = '#';
  managerLink.innerText = 'Managers';
  managerLink.addEventListener('click', function(event) {
    event.preventDefault();
    this.classList.toggle('active');
    var content = document.getElementById('managers');
    if (content.style.display === 'block') {
      content.style.display = 'none';
    } else {
      content.style.display = 'block';
    }
  });
  managerHeader.appendChild(managerLink);

  var managerOL = document.createElement('ol');
  managerOL.id = 'managers';
  managerOL.style.display = 'block';
  manager[0].appendChild(managerHeader);
  var li;
  for (var i = 0; i < managers.length; i++) {
    li = document.createElement('li');
    li.id = 'manager_' + managers[i].id;
    li.innerText = 'Manager ' + managers[i].id +
        ' logged time: ' +
        logHelper.formatElapsedMS(
            managers[i].endTime - managers[i].startTime) +
        'ms' +
        ' total scans: ' + managers[i].scans +
        ' seen services: ' + managers[i].services.length;
    li.className = 'manager';
    if (managers[i].notes && managers[i].notes.length > 0) {
      li.appendChild(displayNotes(logSummary, managers[i].notes));
    }
    li.appendChild(displayServices(logSummary, managers[i].services));
    managerOL.appendChild(li);
  }
  manager[0].appendChild(managerOL);
}

/**
 * Method to display the services observed in the netlog.
 *
 * @param {LogSummary} logSummary Object holding state from processing the log.
 * @param {Service[]} serviceList List of services to display.
 * @return {node} Document node element containing the service list.
 * @private
 */
function displayServices(logSummary, serviceList) {
  var serviceOL = document.createElement('ol');
    for (var j = 0; j < serviceList.length; j++) {
      var sId = serviceList[j].serviceId;
      var serviceLI = document.createElement('li');
      serviceLI.innerText = 'Service ' + sId;
      serviceLI.id = 'service_' + sId;
      serviceLI.className = 'service';
      if (serviceList[j].notes && serviceList[j].notes.length > 0) {
        serviceLI.appendChild(displayNotes(logSummary, serviceList[j].notes));
      }
      serviceLI.appendChild(displayServiceStates(logSummary,
                                                 serviceList[j].states));
      serviceOL.appendChild(serviceLI);
    }
    return serviceOL;
}

/**
 * Method to display individual service states and failure reasons (if any).
 *
 * @param {LogSummary} logSummary Object holding state from processing the log.
 * @param {Update[]} stateList Observed updates for a service.
 * @return {node} Document node element containing the list of service states.
 * @private
 */
function displayServiceStates(logSummary, stateList) {
  var stateOL = document.createElement('ol');
  for (var z = 0; z < stateList.length; z++) {
    var stateLI = document.createElement('li');
    var anchor = document.createElement('a');
    var text = document.createElement('span');
    anchor.href = '#' + stateList[z].time;
    anchor.innerText = '[' + stateList[z].time + ']';
    text.innerText = ' [' +
        logHelper.formatElapsedMS(
            Date.parse(stateList[z].time) - logSummary.logStartTime) + '] ' +
        stateList[z].state;
    if (stateList[z].failure) {
      text.innerText += ' [' + stateList[z].failure + ']';
    }
    stateLI.appendChild(anchor);
    stateLI.appendChild(text);
    if (stateList[z].notes && stateList[z].notes.length > 0) {
      stateLI.appendChild(displayNotes(logSummary, stateList[z].notes));
    }
    stateOL.appendChild(stateLI);
  }
  return stateOL;
}

/**
 * Method to display individual notes for a service or manager.
 *
 * @param {LogSummary} logSummary Object holding state from processing the log.
 * @param {Update[]} noteList Observed notes.
 * @return {node} Document node containing the notes for a service or manager.
 * @private
 */
function displayNotes(logSummary, noteList) {
  if (noteList == null) {
    return;
  }
  var noteOL = document.createElement('ol');
  noteOL.className = 'notes';
  for (var n = 0; n < noteList.length; n++) {
    var noteLI = document.createElement('li');
    var anchor = document.createElement('a');
    var text = document.createElement('span');
    anchor.href = '#' + noteList[n].time;
    anchor.innerText = '[' + noteList[n].time + ']';
    text.innerText = ' [' +
        logHelper.formatElapsedMS(
            Date.parse(noteList[n].time) - logSummary.logStartTime) + ']  ' +
        noteList[n].message;
    noteLI.appendChild(anchor);
    noteLI.appendChild(text);
    noteOL.appendChild(noteLI);
  }
  return noteOL;
}

/**
 * Method to display the log lines after the summary by appending a preformatted
 * (<pre>) element to the document.
 *
 * @param {Object[]} logHolder Object holding log subsections.
 * @private
 */
function displayLog(logHolder) {
  var mergedLog = [];
  // merge all log types together...
  var netLength = 0;
  if (logHolder.netlog)
    netLength = logHolder.netlog.length;
  if (logHolder.brillolog) {
    if (logHolder.netlog) {
      console.error('processor holds netlog and brillo log - error!');
      return;
    }
    netLength = logHolder.brillolog.length;
    logHolder.netlog = logHolder.brillolog;
  }
  var sysLength = 0;
  if (logHolder.syslog)
    sysLength = logHolder.syslog.length;

  if (logHolder.androidlog) {
    console.log('attempting to display an android log');
    netLength = logHolder.androidlog.length;
    logHolder.netlog = logHolder.androidlog;
  }

  while (netLength > 0 || sysLength > 0) {
    if (netLength == 0) {
      mergedLog.appendLog(logHolder.syslog);
      sysLength = 0;
    } else if (sysLength == 0) {
      mergedLog.appendLog(logHolder.netlog);
      netLength = 0;
    } else {
      if (logHolder.netlog[0].ts < logHolder.syslog[0].ts) {
        mergedLog.push(logHolder.netlog.shift());
        netLength -= 1;
      } else if (logHolder.netlog[0].ts > logHolder.syslog[0].ts) {
        mergedLog.push(logHolder.syslog.shift());
        sysLength -= 1;
      } else {
        //the log times are equal - grab them both for proper interleaving
        mergedLog.push(logHolder.syslog.shift());
        sysLength -= 1;
        mergedLog.push(logHolder.netlog.shift());
        netLength -= 1;
      }
    }
  }

  if (mergedLog.length == 0) {
    return;
  }
  var manager = document.getElementsByClassName('managers');
  var logTextHeader = document.createElement('h2');
  manager[0].appendChild(logTextHeader);
  var logTextLink = document.createElement('a');
  logTextLink.href = '#';
  logTextLink.innerText = 'Merged Log View';
  logTextLink.addEventListener('click', function(event) {
    event.preventDefault();
    this.classList.toggle('active');
    var content = document.getElementById('logText');
    if (content.style.display === 'block') {
      content.style.display = 'none';
    } else {
      content.style.display = 'block';
    }
  });
  logTextHeader.appendChild(logTextLink);

  var logText = document.createElement('div');
  logText.id = 'logText';
  logText.style.display = 'block';

  var logTextHolder;
  var fileLabel;
  var logTextHolder2;
  var anchor;
  var fileMark;
  var mark;
  for (var i = 0; i < mergedLog.length; i++) {
    mark = null;
    logTextHolder = document.createElement('pre');
    fileLabel = document.createElement('span');
    fileLabel.class = 'inner-pre file';
    fileLabel.textContent = mergedLog[i].file;
    fileMark = document.createElement('mark');
    fileMark.className = mergedLog[i].file;
    fileMark.appendChild(fileLabel);
    logTextHolder.appendChild(fileMark);
    logTextHolder2 = document.createElement('span');
    logTextHolder2.class = 'inner-pre';
    logTextHolder2.textContent += mergedLog[i].text;
    if (mergedLog[i].tag) {
      mark = document.createElement('mark');
      mark.className = mergedLog[i].type;
      anchor = document.createElement('a');
      anchor.name = mergedLog[i].tag;
      logTextHolder.appendChild(anchor);
    }
    if (mark) {
      mark.appendChild(logTextHolder2);
      logTextHolder.appendChild(mark);
    } else {
      logTextHolder.appendChild(logTextHolder2);
    }
    logText.appendChild(logTextHolder);
  }
  logTextHeader.appendChild(logText);
}

/**
 * Helper method to move and append one log to another.
 *
 * @param {Object[]} toCopy LogLine entries to move.
 */
Array.prototype.appendLog = function(toCopy) {
  toCopy.forEach(function(x) {
    this.push(x);
  },
  this);
  toCopy.length = 0;
};
