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

module.exports = Playground;

var _ = require('lodash');
var http = require('http');
var moment = require('moment');
var path = require('path');
var superagent = require('superagent');
var url = require('url');

var m = require('mercury');
var h = m.h;

var Editor = require('./widgets/editor');
var Spinner = require('./widgets/spinner');

// Timeout for save and load requests, in milliseconds.
var storageRequestTimeout = 1000;

// Shows each file in a tab.
// * el: The DOM element to mount on.
// * name: Name of this playground instance, used in debug messages.
// * bundle: The default bundle formatted as {files:[{name, body}]}, as written
//           by pgbundle, to use if id is unspecified or if load fails.
function Playground(el, name, bundle) {
  this.name_ = name;
  this.defaultBundle_ = bundle;
  this.files_ = [];
  this.editors_ = [];
  this.editorSpinner_ = new Spinner();
  // scrollState_ changes should not trigger render_, thus are not monitored
  // by mercury.
  this.scrollState_ = {bottom: true};
  // Mercury framework state. Changes to state trigger virtual DOM render.
  var state = m.state({
    notification: m.value({}),
    // False on page load (no bundle), empty if default bundle is loaded.
    bundleId: m.value(false),
    // Incrementing counter on each bundle reload to force render.
    bundleVersion: m.value(0),
    activeTab: m.value(0),
    idToLoad: m.value(''),
    // Save or load request in progress.
    requestActive: m.value(false),
    nextRunId: m.value(0),
    running: m.value(false),
    hasRun: m.value(false),
    consoleEvents: m.value([]),
    // Mercury framework channels. References to event handlers callable from
    // rendering code.
    channels: {
      switchTab: this.switchTab.bind(this),
      setIdToLoad: this.setIdToLoad.bind(this),
      // For testing. Load in production can be done purely using links.
      // Reload is not necessary before adding history.
      load: this.load.bind(this),
      save: this.save.bind(this),
      run: this.run.bind(this),
      stop: this.stop.bind(this),
      reset: this.reset.bind(this)
    }
  });
  m.app(el, state, this.render_.bind(this));
  // When page is first loaded, load bundle in url.
  this.loadUrl_(state, window.location.href);
  // When user goes forward/back, load bundle in url.
  var that = this;
  window.addEventListener('popstate', function(ev) {
    console.log('window.onpopstate', ev);
    that.loadUrl_(state, window.location.href);
  });
  // Enable ev-scroll listening.
  m.Delegator().listenTo('scroll');
}

// Attempts to load the bundle with id specified in the url, or the default
// bundle if id is not specified.
Playground.prototype.loadUrl_ = function(state, pgurl) {
  this.setNotification_(state);
  this.url_ = url.parse(pgurl, true);
  // Deleted to make url.format() use this.url_.query.
  delete this.url_.search;
  var bId = this.url_.query.id || '';
  // Filled into idToLoad to allow retrying using Load button.
  state.idToLoad.set(bId);
  if (bId) {
    console.log('Loading bundle', bId, 'from URL');
    process.nextTick(this.load.bind(this, state, {id: bId}));
  } else {
    console.log('Loading default bundle');
    process.nextTick(
      this.setBundle_.bind(this, state, this.defaultBundle_, ''));
  }
};

// Builds bundle object from editor contents.
Playground.prototype.getBundle_ = function() {
  var editors = this.editors_;
  return {
    files: _.map(this.files_, function(file, i) {
      var editor = editors[i];
      return {
        name: file.name,
        body: editor.getText()
      };
    })
  };
};

// Loads bundle object into editor contents, updates url.
Playground.prototype.setBundle_ = function(state, bundle, id) {
  this.files_ = _.map(bundle.files, function(file) {
    return _.assign({}, file, {
      basename: path.basename(file.name),
      type: path.extname(file.name).substr(1)
    });
  });
  this.editors_ = _.map(this.files_, function(file) {
    return new Editor(file.type, file.body);
  });
  state.activeTab.set(0);
  this.resetState_(state);
  state.bundleId.set(id);
  // Increment counter in state to force render.
  state.bundleVersion.set((state.bundleVersion() + 1) & 0x7fffffff);
  this.setUrlForId_(id);
};

// Updates url with new id if different from the current one.
Playground.prototype.setUrlForId_ = function(id) {
  if (!id && !this.url_.query.id || id === this.url_.query.id) {
    return;
  }
  if (!id) {
    delete this.url_.query.id;
  } else {
    this.url_.query.id = id;
  }
  window.history.pushState(null, '', url.format(this.url_));
};

// Determines base url for backend calls.
Playground.prototype.getBackendUrl_ = function() {
  var pgaddr = this.url_.query.pgaddr;
  if (pgaddr) {
    if (window.location.hostname === 'localhost') {
      console.log('Using pgaddr', pgaddr);
      return pgaddr;
    } else {
      console.error('pgaddr disabled on non-localhost clients');
      pgaddr = '';
    }
  }
  var origin = window.location.protocol + '//' + window.location.host;
  var defaddr = origin + '/api';
  console.log('Using default backend', defaddr);
  return defaddr;
};

// Shows notification, green if success is set, red otherwise.
// Call with undefined/blank msg to clear notification.
Playground.prototype.setNotification_ = function(state, msg, success) {
  if (!msg) {
    state.notification.set({});
  } else {
    state.notification.set({message: msg, ok: success});
    // TODO(ivanpi): Expire message.
  }
};

// Renders button with provided label and target.
// If disable is true or a request is active, the button is disabled.
Playground.prototype.button_ = function(state, label, target, disable) {
  if (disable || state.requestActive) {
    return h('button.btn', {
      disabled: true
    }, label);
  } else {
    return h('button.btn', {
      'ev-click': target
    }, label);
  }
};

Playground.prototype.renderLoadBar_ = function(state) {
  var idToLoad = h('input.bundleid', {
    type: 'text',
    name: 'idToLoad',
    size: 64,
    maxLength: 64,
    value: state.idToLoad,
    'ev-input': m.sendChange(state.channels.setIdToLoad)
  });
  var loadBtn = this.button_(state, 'Load',
    m.sendClick(state.channels.load, {id: state.idToLoad}),
    state.running);

  return h('div.widget-bar', [
    h('span', [idToLoad]),
    h('span.btns', [loadBtn])
  ]);
};

Playground.prototype.renderResetBar_ = function(state) {
  var idShow = h('span.bundleid',
    state.bundleId || (state.bundleId === '' ? '<default>' : '<none>'));
  var link = h('a', {
    href: window.location.href
  }, 'link');
  var notif = h('span.notif.' + (state.notification.ok ? 'success' : 'error'),
    state.notification.message || '');

  var resetBtn = this.button_(state, 'Reset',
    m.sendClick(state.channels.reset),
    state.bundleId === false);
  var reloadBtn = this.button_(state, 'Reload',
    m.sendClick(state.channels.load, {id: state.bundleId}),
    state.running || !state.bundleId);

  return h('div.widget-bar', [
    h('span', [idShow, ' ', link, ' ', notif]),
    h('span.btns', [resetBtn, reloadBtn])
  ]);
};

Playground.prototype.renderTabBar_ = function(state) {
  var tabs = _.map(this.files_, function(file, i) {
    var selector = 'div.tab';
    if (i === state.activeTab) {
      selector += '.active';
    }
    return h(selector, {
      'ev-click': m.sendClick(state.channels.switchTab, {index: i})
    }, file.basename);
  });

  var runStopBtn = state.running ?
    this.button_(state, 'Stop', m.sendClick(state.channels.stop)) :
    this.button_(state, 'Run', m.sendClick(state.channels.run),
      state.bundleId === false);
  var saveBtn = this.button_(state, 'Save',
    m.sendClick(state.channels.save),
    state.running || (state.bundleId === false));

  return h('div.widget-bar', [
    h('span', tabs),
    h('span.btns', [runStopBtn, saveBtn])
  ]);
};

Playground.prototype.renderEditors_ = function(state) {
  var editors = _.map(this.editors_, function(editor, i) {
    var properties = {};
    if (i !== state.activeTab) {
      // Use "visibility: hidden" rather than "display: none" because the latter
      // causes the editor to initialize lazily and thus flicker when it's first
      // opened.
      properties['style'] = {visibility: 'hidden'};
    }
    return h('div.editor', properties, editor);
  });

  if (state.requestActive) {
    editors.push(this.editorSpinner_);
  }

  return h('div.editors', editors);
};

Playground.prototype.renderConsoleEvent_ = function(event) {
  var children = [];
  if (event.Timestamp) {
    // Convert UTC to local time.
    var t = moment(event.Timestamp / 1e6);
    children.push(h('span.timestamp', t.format('H:mm:ss.SSS') + ' '));
  }
  if (event.File) {
    children.push(h('span.filename', path.basename(event.File) + ': '));
  }
  // A single trailing newline is always ignored.
  // Ignoring the last character, check if there are any newlines in message.
  if (event.Message.slice(0, -1).indexOf('\n') !== -1) {
    // Multiline messages are marked with U+23CE and started in a new line.
    children.push('\u23ce'/* U+23CE RETURN SYMBOL */, h('br'));
  }
  children.push(h('span.message.' + (event.Stream || 'unknown'),
                  event.Message));
  return h('div', children);
};

// ScrollHandle provides a hook to keep the console scrolled to the bottom
// unless the user has scrolled up, and the update method to detect the
// user scrolling up.
function ScrollHandle(scrollState) {
  this.scrollState_ = scrollState;
  this.enableScrollUpdates_ = false;
}

ScrollHandle.prototype.hook = function(elem, propname) {
  var that = this;
  process.nextTick(function() {
    if (that.scrollState_.bottom) {
      elem.scrollTop = elem.scrollHeight - elem.clientHeight;
    }
    that.enableScrollUpdates_ = true;
  });
};

ScrollHandle.prototype.update = function(ev) {
  var el = ev.currentTarget;
  if (this.enableScrollUpdates_) {
    // scrollHeight and clientHeight are rounded to an integer, so we need to
    // compare fuzzily.
    this.scrollState_.bottom =
        Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) <= 2.01;
  }
};

Playground.prototype.renderConsole_ = function(state) {
  if (state.hasRun) {
    var scrollHandle = new ScrollHandle(this.scrollState_);
    return h('div.console.open', {
      'ev-scroll': scrollHandle.update.bind(scrollHandle),
      'scrollhook': scrollHandle
    }, [
      h('div.text', _.map(state.consoleEvents, this.renderConsoleEvent_))
    ]);
  }
  return h('div.console');
};

Playground.prototype.render_ = function(state) {
  return h('div.pg', [
    this.renderLoadBar_(state),
    this.renderResetBar_(state),
    this.renderTabBar_(state),
    this.renderEditors_(state),
    this.renderConsole_(state)
  ]);
};

// Switches active tab to data.index.
Playground.prototype.switchTab = function(state, data) {
  this.setNotification_(state);
  state.activeTab.set(data.index);
};

// Reads the idToLoad text box into state.
Playground.prototype.setIdToLoad = function(state, formdata) {
  this.setNotification_(state);
  state.idToLoad.set(formdata.idToLoad);
};

Playground.prototype.showMessage_ = function(state, prefix, msg, ok) {
  var fullMsg = prefix + ': ' + msg;
  if (ok) {
    console.log(fullMsg);
  } else {
    console.error(fullMsg);
  }
  this.setNotification_(state, fullMsg, ok);
};

// Returns callback to be used for save and load requests. Callback loads the
// bundle returned from the server and updates bundleId and url.
Playground.prototype.saveLoadCallback_ = function(state, operation) {
  var that = this;
  return function(rerr, res) {
    state.requestActive.set(false);
    var processResponse = function() {
      if (rerr) {
        if (rerr.timeout) {
          return 'request timed out';
        }
        return 'error connecting to server: ' + rerr;
      }
      if (res.body && res.body.Error) {
        // TODO(ivanpi): Special handling of 404? Retry on other errors?
        return 'error ' + res.status + ': ' + res.body.Error;
      }
      if (res.error) {
        return 'error ' + res.status + ': unknown';
      }
      if (!res.body.Link || !res.body.Data) {
        return 'invalid response format';
      }
      var bundle;
      try {
        bundle = JSON.parse(res.body.Data);
      } catch (jerr) {
        return 'error parsing Data: ' + res.body.Data + '\n' + jerr.message;
      }
      // Opens bundle in editors, updates bundleId and url.
      that.setBundle_(state, bundle, res.body.Link);
      return null;
    };
    var errm = processResponse();
    if (!errm) {
      state.idToLoad.set('');
      that.showMessage_(state, operation, 'success', true);
    } else {
      // Load/save failed.
      if (state.bundleId() === false) {
        // If no bundle was loaded, load default.
        that.setBundle_(state, that.defaultBundle_, '');
      } else {
        // Otherwise, reset url to previously loaded bundle.
        that.setUrlForId_(state.bundleId());
      }
      that.showMessage_(state, operation, errm);
    }
  };
};

// Loads bundle for data.id.
Playground.prototype.load = function(state, data) {
  this.setNotification_(state);
  if (!data.id) {
    this.showMessage_(state, 'load', 'cannot load blank id');
    return;
  }
  superagent
    .get(this.getBackendUrl_() + '/load?id=' + encodeURIComponent(data.id))
    .accept('json')
    .timeout(storageRequestTimeout)
    .end(this.saveLoadCallback_(state, 'load ' + data.id));
  state.requestActive.set(true);
};

// Saves bundle and updates bundleId with the received id.
Playground.prototype.save = function(state) {
  this.setNotification_(state);
  superagent
    .post(this.getBackendUrl_() + '/save')
    .type('json')
    .accept('json')
    .timeout(storageRequestTimeout)
    .send(this.getBundle_())
    .end(this.saveLoadCallback_(state, 'save'));
  state.requestActive.set(true);
};

// Sends the files to the compile backend, streaming the response into the
// console.
Playground.prototype.run = function(state) {
  if (state.running()) {
    console.log('Already running', this.name_);
    return;
  }
  var runId = state.nextRunId();

  this.setNotification_(state);
  state.running.set(true);
  state.hasRun.set(true);
  state.consoleEvents.set([{Message: 'Running...'}]);
  this.scrollState_.bottom = true;

  var compileUrl = this.getBackendUrl_() + '/compile';
  if (this.url_.query.debug === '1') {
    compileUrl += '?debug=1';
  }

  var reqData = this.getBundle_();

  // TODO(sadovsky): To deal with cached responses, shift timestamps (based on
  // current time) and introduce a fake delay. Also, switch to streaming
  // messages, for usability.
  var that = this;

  // If the user stops the current run or resets the playground, functions
  // wrapped with ifRunActive become no-ops.
  var ifRunActive = function(cb) {
    return function() {
      if (runId === state.nextRunId()) {
        cb.apply(this, arguments);
      }
    };
  };

  var appendToConsole = function(events) {
    state.consoleEvents.set(state.consoleEvents().concat(events));
  };
  var makeEvent = function(stream, message) {
    return {Stream: stream, Message: message};
  };

  var urlp = url.parse(compileUrl);

  var options = {
    method: 'POST',
    protocol: urlp.protocol,
    hostname: urlp.hostname,
    port: urlp.port || (urlp.protocol === 'https:' ? '443' : '80'),
    path: urlp.path,
    // TODO(ivanpi): Change once deployed.
    withCredentials: false,
    headers: {
      'accept': 'application/json',
      'content-type': 'application/json'
    }
  };

  var req = http.request(options);

  var watchdog = null;
  // The heartbeat function clears the existing timeout (if any) and, if the run
  // is still active, starts a new timeout.
  var heartbeat = function() {
    if (watchdog !== null) {
      clearTimeout(watchdog);
    }
    watchdog = null;
    ifRunActive(function() {
      // TODO(ivanpi): Reduce timeout duration when server heartbeat is added.
      watchdog = setTimeout(function() {
        process.nextTick(ifRunActive(function() {
          req.destroy();
          appendToConsole(makeEvent('syserr', 'Server response timed out.'));
        }));
      }, 10500);
    })();
  };

  var endRunIfActive = ifRunActive(function() {
    that.stop(state);
    // Cleanup watchdog timer.
    heartbeat();
  });

  // error and close callbacks call endRunIfActive in the next tick to ensure
  // that if both events are triggered, both are executed before the run is
  // ended by either.
  req.on('error', ifRunActive(function(err) {
    console.error('Connection error: ' + err.message + '\n' + err.stack);
    appendToConsole(makeEvent('syserr', 'Error connecting to server.'));
    process.nextTick(endRunIfActive);
  }));

  // Holds partial prefix of next response line.
  var partialLine = '';

  req.on('response', ifRunActive(function(res) {
    heartbeat();
    if (res.statusCode !== 0 && res.statusCode !== 200) {
      appendToConsole(makeEvent('syserr', 'HTTP status ' + res.statusCode));
    }
    res.on('data', ifRunActive(function(chunk) {
      heartbeat();
      // Each complete line is one JSON Event.
      var eventsJson = (partialLine + chunk).split('\n');
      partialLine = eventsJson.pop();
      var events = [];
      _.forEach(eventsJson, function(line) {
        // Ignore empty lines.
        line = line.trim();
        if (line) {
          var ev;
          try {
            ev = JSON.parse(line);
          } catch (err) {
            console.error('Error parsing line: ' + line + '\n' + err.message);
            events.push(makeEvent('syserr', 'Error parsing server response.'));
            endRunIfActive();
            return false;
          }
          events.push(ev);
        }
      });
      appendToConsole(events);
    }));
  }));

  req.on('close', ifRunActive(function() {
    // Sanity check: partialLine should be empty when connection is closed.
    partialLine = partialLine.trim();
    if (partialLine) {
      console.error('Connection closed without newline after: ' + partialLine);
      appendToConsole(makeEvent('syserr', 'Error parsing server response.'));
    }
    process.nextTick(endRunIfActive);
  }));

  req.write(JSON.stringify(reqData));
  req.end();

  // Start watchdog.
  heartbeat();
};

// Clears the console and resets all editors to their original contents.
Playground.prototype.reset = function(state) {
  this.resetState_(state);
  _.forEach(this.editors_, function(editor) {
    editor.reset();
  });
  this.setUrlForId_(state.bundleId());
};

Playground.prototype.resetState_ = function(state) {
  state.consoleEvents.set([]);
  this.scrollState_.bottom = true;
  this.stop(state);
  state.hasRun.set(false);
};

// Stops bundle execution.
Playground.prototype.stop = function(state) {
  this.setNotification_(state);
  state.nextRunId.set((state.nextRunId() + 1) & 0x7fffffff);
  state.running.set(false);
};
