/// <reference path="kubernetesPlugin.ts"/>
/// <reference path="watcher.ts"/>

module Kubernetes {

  var log = Logger.get("kubernetes-term-windows");

  _module.config((kubernetesContainerSocketProvider) => {
    kubernetesContainerSocketProvider.WebSocketFactory = "CustomWebSockets";
  });

  _module.factory('CustomWebSockets', (userDetails:any) => {
    return function CustomWebSocket(url, protocols) {
      var paths = url.split('?');
      if (!_.startsWith(paths[0], masterApiUrl())) {
        paths[0] = UrlHelpers.join(masterApiUrl(), paths[0]);
      }
      url = KubernetesAPI.wsUrl(paths[0]);
      url.search(paths[1] + '&access_token=' + userDetails.token);
      log.debug("Using ws url: ", url.toString());
      return new WebSocket(url.toString(), protocols);
    };
  });

  _module.service('TerminalService', ($rootScope, $document, $compile, $interval, $templateCache) => {
    var body = $document.find('body');
    function positionTerminals(terminals) {
      var total = _.keys(terminals).length;
      var dist = (body.width() - 225) / total;
      var position = 5;
      angular.forEach(terminals, (value, key) => {
        if (!value.scope.docked) {
          return;
        }
        value.el.css('left', position + 'px');
        position = position + dist;
      });
    }
    var defaultTemplate = $templateCache.get(UrlHelpers.join(templatePath, 'termShell.html'));
    var self = {
      positionTerminals: () => {
        positionTerminals(self.terminals);
      },
      terminals: {},
      httpTask: {},
      newTerminal: ($interval, podLink, containerName, entity, template = defaultTemplate) => {
        var terminalId = UrlHelpers.join(podLink, containerName);
        if (terminalId in self.terminals) {
          log.debug("Already a terminal with id: ", terminalId);
          self.raiseTerminal(terminalId);
          return terminalId;
        }
        var scope = $rootScope.$new();
        getLogs(entity, scope);
        scope.podLink = podLink;
        scope.containerName = containerName;
        scope.id = terminalId;
        scope.docked = true;
        if(terminalId in self.httpTask){
           self.raiseTerminal(terminalId);
           return terminalId;
        }else{
           self.httpTask[terminalId] = $interval(() =>{
              getLogs(entity, scope);
           },2000);
        }
        var el = $($compile(template)(scope));
        var term = {
          scope: scope,
          el: el
        };
        body.append(el);
        self.terminals[terminalId] = term;
        positionTerminals(self.terminals);
        return terminalId;
      },
      closeTerminal: (id) => {
        var term = self.terminals[id];
        var timer = self.httpTask[id];
        if(timer){
          $interval.cancel(timer);
          delete self.httpTask[id];
        }
        if (term) {
          term.el.remove();
          delete self.terminals[id];
          positionTerminals(self.terminals);
        }
      },
      raiseTerminal: (id) => {
        angular.forEach(self.terminals, (value, key) => {
          if (key === id) {
            value.el.css('z-index', '4000');
            value.el.find('.terminal').focus();
          } else {
            value.el.css('z-index', '3000');
          }
        });
      }
    };
    return self;
  });

  export function addWindowActions(scope, element, TerminalService) {
    var moved = false;
    var lastX = 0;
    var lastY = 0;
    var header = element.find('.terminal-title');
    var body = element.find('.terminal-body');
    element.on('$destroy', () => {
      $('#main').css({ display: 'inherit' });
    });

    var HEIGHT = 348;
    var WIDTH = 600;
    var TITLE_HEIGHT = 35;
    var NAV_OFFSET = 46;

    element.css({
      height: HEIGHT,
      width: WIDTH
    });
    header.css({
      height: TITLE_HEIGHT
    });
    body.css({
      position: 'absolute',
      top: 35,
      left: 0,
      right: 0, 
      bottom: 0
    });
    scope.close = () => {
      TerminalService.closeTerminal(scope.id);
    };
    scope.raise = () => {
      TerminalService.raiseTerminal(scope.id);
    };
    scope.$watch('docked', (docked) => {
      if (docked) {
        element.width(WIDTH);
        if (!element.hasClass('minimized')) {
          element.height(HEIGHT);
        }
      }
    });
    scope.startResize = (e) => {
      e.preventDefault();
      log.debug("Start resize");
      scope.resizing = true;
      element.on('mouseup', scope.stopResize);
      $(document).on('mousemove', scope.doResize);
      $(document).on('mouseleave', scope.stopResize);
    };
    scope.doResize = (e) => {
      if (scope.resizing) {
        log.debug("Resizing, e: ", e);
        if (!moved) {
          lastX = e.clientX;
          lastY = e.clientY;
          moved = true;
          return;
        }
        var height = element.height();
        var width = element.width();
        var deltaX = e.clientX - lastX;
        var deltaY = e.clientY - lastY;
        var newHeight = height + deltaY;
        var newWidth = width + deltaX;
        if (newHeight > 35 && newWidth > 80) {
          element.height(height + deltaY);
          element.width(width + deltaX);
        }
        lastX = e.clientX;
        lastY = e.clientY;
      }
    };
    scope.stopResize = (e) => {
      scope.resizing = false;
      moved = false;
      element.off('mouseup', scope.stopResize);
      $(document).off('mousemove', scope.doResize);
      $(document).off('mouseleave', scope.stopResize);
    }
    scope.mouseDown = (e) => {
      e.preventDefault();
      if (element.hasClass('minimized') || element.hasClass('maximized')) {
        return;
      }
      scope.dragging = true;
      element.on('mouseup', scope.mouseUp);
      $(document).on('mousemove', scope.mouseMove);
      $(document).on('mouseleave', scope.mouseUp);
    };
    scope.mouseUp = (e) => {
      e.preventDefault();
      scope.dragging = false;
      moved = false;
      var height = element.height();
      var offset = element.offset();
      var winHeight = $(window).height();
      if (offset.top > (winHeight - height - 20)) {
        element.css({ top: "inherit", left: "inherit" });
        scope.docked = true;
        TerminalService.positionTerminals();
      } else {
        scope.docked = false;
      }
      element.off('mouseup', scope.mouseUp);
      $(document).off('mousemove', scope.mouseMove);
      $(document).off('mouseleave', scope.mouseUp);
    };
    scope.mouseMove = (e) => {
      if (scope.dragging) {
        if (!moved) {
          lastX = e.clientX;
          lastY = e.clientY;
          moved = true;
          return;
        }
        var deltaX = e.clientX - lastX;
        var deltaY = e.clientY - lastY;
        var elOffset = element.offset();
        element.offset({ top: elOffset.top + deltaY, left: elOffset.left + deltaX });
        lastX = e.clientX;
        lastY = e.clientY;
      }
    }

    function restoreWindow(scope, element) {
      if (scope.offset) {
        element.offset(scope.offset);
        scope.docked = false;
      }
      if (scope.height) {
        element.height(scope.height);
      }
      if (scope.width) {
        element.width(scope.width);
      }
    }

    function saveWindow(scope, element) {
      scope.offset = element.offset();
      scope.height = element.height();
      scope.width = element.width();
    }

    scope.maximized = () => {
      return element.hasClass('maximized');
    }

    scope.maximize = ($e) => {
      $e.preventDefault();
      if (element.hasClass('minimized')) {
        scope.minimize();
      }
      if (element.hasClass('maximized')) {
        restoreWindow(scope, element);
        $('#main').css({ display: 'inherit' });
      } else {
        saveWindow(scope, element);
        $('#main').css({ display: 'none' });
        element.css({ 
          height: 'inherit', 
          bottom: 0, 
          width: '100%', 
          top: NAV_OFFSET, 
          left: 0 
        });
      }
      element.toggleClass('maximized');
    }
    scope.minimize = ($e) => {
      $e.preventDefault();
      if (element.hasClass('maximized')) {
        scope.maximize();
      }
      if (element.hasClass('minimized')) {
        restoreWindow(scope, element);
      } else {
        saveWindow(scope, element);
        scope.docked = true;
        element.css({ height: TITLE_HEIGHT, top: "inherit", left: "inherit" });
        TerminalService.positionTerminals();
      }
      element.toggleClass('minimized');
    };
  }

  _module.directive('terminalWindow', ($compile, TerminalService) => {
    return {
      restrict: 'A',
      scope: false,
      link: (scope:any, element, attr) => {
        addWindowActions(scope, element, TerminalService);
        var body = element.find('.terminal-body');
        body.append($compile('<kubernetes-container-terminal pod="podLink" container="containerName" command="bash"></kubernetes-container-terminal>')(scope));
      }
    };
  });

  function getLogs(rc, scope){    
     var xhr= new XMLHttpRequest();
     xhr.onreadystatechange = () => {
        if(xhr.readyState == 4){
           if (xhr.status == 200){
               if(xhr.responseText !="" && xhr.responseText !=null){                  
                  var logObject = JSON.parse(xhr.responseText);  
                  scope.logs = logObject[getName(rc)];
                }else{
                  scope.logs = "当前没有可以查看的日志信息";
                }
               
               //return ({text: "aaaaaa"});

           }else{
               //log = "当前没有可以查看的日志!";
           }
        }
     }
     xhr.open("POST", "/java/console/api/oracle/extract/log?rcName=" + getName(rc),false);
     xhr.send(null);
  }
}