import {Terminal} from 'xterm';
import style from 'xterm/dist/xterm.css';
import * as attach from 'xterm/lib/addons/attach/attach';
import * as fit from 'xterm/lib/addons/fit/fit';
var configJSON = require('../../../config.json');
if (configJSON.keyType == 'VT100+') {
  var vt100PlusKey = require('./vt100plus');
}

var customKeyHandlers = function(ev) {
  if (configJSON.keyType == 'VT100+') {
    return vt100PlusKey.customVT100PlusKey(ev, this);
  }
  return true;
};

function measureChar(term) {
  var span = document.createElement('span');
  var fontFamily = 'courier-new';
  var fontSize = 15;
  var rect;

  span.textContent = 'W';
  try {
    fontFamily = term.getOption('fontFamily');
    fontSize = term.getOption('fontSize');
  } catch (err) {
    console.log('get option failure');
  }
  span.style.fontFamily = fontFamily;
  span.style.fontSize = fontSize + 'px';
  document.body.appendChild(span);
  rect = span.getBoundingClientRect();
  document.body.removeChild(span);
  return rect;
}

// Add a TextEncoder polyfill to handle ie9 properly.  (does anyone still use
// that anymore? Grabbed from
// https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder#Polyfill
if (typeof TextEncoder === 'undefined') {
  let TextEncoder = function TextEncoder() {};
  TextEncoder.prototype.encode = function encode(str) {
    var Len = str.length, resPos = -1;
    // The Uint8Array's length must be at least 3x the length of the string
    // because an invalid UTF-16
    //  takes up the equivelent space of 3 UTF-8 characters to encode it
    //  properly. However, Array's have an auto expanding length and 1.5x should
    //  be just the right balance for most uses.
    var resArr = typeof Uint8Array === 'undefined' ? new Array(Len * 1.5) :
                                                     new Uint8Array(Len * 3);
    for (var point = 0, nextcode = 0, i = 0; i !== Len;) {
      point = str.charCodeAt(i), i += 1;
      if (point >= 0xD800 && point <= 0xDBFF) {
        if (i === Len) {
          resArr[resPos += 1] = 0xef /*0b11101111*/;
          resArr[resPos += 1] = 0xbf /*0b10111111*/;
          resArr[resPos += 1] = 0xbd /*0b10111101*/;
          break;
        }
        // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
        nextcode = str.charCodeAt(i);
        if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) {
          point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000;
          i += 1;
          if (point > 0xffff) {
            resArr[resPos += 1] = (0x1e /*0b11110*/ << 3) | (point >>> 18);
            resArr[resPos += 1] =
                (0x2 /*0b10*/ << 6) | ((point >>> 12) & 0x3f /*0b00111111*/);
            resArr[resPos += 1] =
                (0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f /*0b00111111*/);
            resArr[resPos += 1] =
                (0x2 /*0b10*/ << 6) | (point & 0x3f /*0b00111111*/);
            continue;
          }
        } else {
          resArr[resPos += 1] = 0xef /*0b11101111*/;
          resArr[resPos += 1] = 0xbf /*0b10111111*/;
          resArr[resPos += 1] = 0xbd /*0b10111101*/;
          continue;
        }
      }
      if (point <= 0x007f) {
        resArr[resPos += 1] = (0x0 /*0b0*/ << 7) | point;
      } else if (point <= 0x07ff) {
        resArr[resPos += 1] = (0x6 /*0b110*/ << 5) | (point >>> 6);
        resArr[resPos += 1] =
            (0x2 /*0b10*/ << 6) | (point & 0x3f /*0b00111111*/);
      } else {
        resArr[resPos += 1] = (0xe /*0b1110*/ << 4) | (point >>> 12);
        resArr[resPos += 1] =
            (0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f /*0b00111111*/);
        resArr[resPos += 1] =
            (0x2 /*0b10*/ << 6) | (point & 0x3f /*0b00111111*/);
      }
    }
    if (typeof Uint8Array !== 'undefined')
      return resArr.subarray(0, resPos + 1);
    // else // IE 6-9
    resArr.length = resPos + 1;  // trim off extra weight
    return resArr;
  };
  TextEncoder.prototype.toString = function() {
    return '[object TextEncoder]'
  };
  try {  // Object.defineProperty only works on DOM prototypes in IE8
    Object.defineProperty(TextEncoder.prototype, 'encoding', {
      get: function() {
        if (TextEncoder.prototype.isPrototypeOf(this))
          return 'utf-8';
        else
          throw TypeError('Illegal invocation');
      }
    });
  } catch (e) { /*IE6-8 fallback*/
    TextEncoder.prototype.encoding = 'utf-8';
  }
  if (typeof Symbol !== 'undefined')
    TextEncoder.prototype[Symbol.toStringTag] = 'TextEncoder';
}

window.angular && (function(angular) {
  'use strict';

  angular.module('app.common.directives').directive('serialConsole', [
    function() {
      return {
        'restrict': 'E',
        'template': require('./serial-console.html'),
        'scope': {'path': '=', 'showTabBtn': '=?'},
        'controller': [
          '$scope', '$cookies', '$window', 'dataService', '$element',
          function($scope, $cookies, $window, dataService, $element) {
            $scope.dataService = dataService;

            // See https://github.com/xtermjs/xterm.js/ for available xterm
            // options

            Terminal.applyAddon(attach);  // Apply the `attach` addon
            Terminal.applyAddon(fit);     // Apply the `fit` addon

            var border = 10;
            var term = new Terminal();
            // Should be a reference to <div id="terminal"></div>
            var terminal = $element[0].firstElementChild.firstElementChild;
            var customConsole;
            var charSize;
            var termContainer;

            term.open(terminal);
            customConsole = configJSON.customConsoleDisplaySize;

            if (customConsole != null) {
              charSize = measureChar(term);
              termContainer = document.getElementById('term-container');
              if (termContainer != null) {
                if (customConsole.width) {
                  termContainer.style.width =
                      (charSize.width * customConsole.width + border) + 'px';
                }
                if (customConsole.height) {
                  terminal.style.height =
                      (charSize.height * customConsole.height + border) + 'px';
                }
              }
            }
            term.fit();
            if (configJSON.customKeyEnable == true) {
              term.attachCustomKeyEventHandler(customKeyHandlers);
            }
            var SOL_THEME = {
              background: '#19273c',
              cursor: 'rgba(83, 146, 255, .5)',
              scrollbar: 'rgba(83, 146, 255, .5)'
            };
            term.setOption('theme', SOL_THEME);
            var hostname = dataService.getHost().replace('https://', '');
            var host = 'wss://' + hostname + '/console0';
            var token = $cookies.get('XSRF-TOKEN');
            try {
              var ws = new WebSocket(host, [token]);
              term.attach(ws);
              ws.onopen = function() {
                console.log('websocket opened');
              };
              ws.onclose = function(event) {
                console.log(
                    'websocket closed. code: ' + event.code +
                    ' reason: ' + event.reason);
              };
            } catch (error) {
              console.log(JSON.stringify(error));
            }
            $scope.openTerminalWindow = function() {
              $window.open(
                  '#/server-control/remote-console-window',
                  'Remote Console Window',
                  'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550');
            };
          }
        ]
      };
    }
  ]);
})(window.angular);
