// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

(function() {
  'use strict';

  angular.module('mesos', ['ngRoute', 'mesos.services', 'ui.bootstrap', 'ui.bootstrap.dialog']).
    config(['paginationConfig', '$routeProvider', function(paginationConfig, $routeProvider) {
      $routeProvider
        .when('/',
          {templateUrl: 'app/home.html', controller: 'HomeCtrl'})
        .when('/agents',
          {templateUrl: 'app/agents/agents.html', controller: 'AgentsCtrl'})
        .when('/agents/:agent_id',
          {templateUrl: 'app/agents/agent.html', controller: 'AgentCtrl'})
        .when('/agents/:agent_id/frameworks/:framework_id',
          {templateUrl: 'app/agents/agent-framework.html', controller: 'AgentFrameworkCtrl'})
        .when('/agents/:agent_id/frameworks/:framework_id/executors/:executor_id',
          {templateUrl: 'app/agents/agent-executor.html', controller: 'AgentExecutorCtrl'})
        .when('/frameworks',
          {templateUrl: 'app/frameworks/frameworks.html', controller: 'FrameworksCtrl'})
        .when('/frameworks/:id',
          {templateUrl: 'app/frameworks/framework.html', controller: 'FrameworkCtrl'})
        .when('/maintenance',
          {templateUrl: 'app/maintenance/maintenance.html', controller: 'MaintenanceCtrl'})
        .when('/offers',
          {templateUrl: 'app/offers/offers.html', controller: 'OffersCtrl'})
        .when('/roles',
          {templateUrl: 'app/roles/roles.html', controller: 'RolesCtrl'})

        // TODO(tomxing): Remove the following '/slaves/*' paths once the
        // slave->agent rename is complete(MESOS-3779).
        .when('/slaves', {redirectTo: '/agents'})
        .when('/slaves/:agent_id', {redirectTo: '/agents/:agent_id'})
        .when('/slaves/:agent_id/frameworks/:framework_id',
          {redirectTo: '/agents/:agent_id/frameworks/:framework_id'})
        .when('/slaves/:agent_id/frameworks/:framework_id/executors/:executor_id',
          {redirectTo: '/agents/:agent_id/frameworks/:framework_id/executors/:executor_id'})

        // Use a non-falsy template so the controller will still be executed.
        // Since the controller is intended only to redirect, the blank template
        // is fine.
        //
        // By design, controllers currently will not handle routes if the
        // template is falsy. There is an issue open in Angular to add that
        // feature:
        //
        //     https://github.com/angular/angular.js/issues/1838
        .when('/agents/:agent_id/frameworks/:framework_id/executors/:executor_id/browse',
          {template: ' ', controller: 'AgentTaskAndExecutorRerouterCtrl'})
        .when('/agents/:agent_id/frameworks/:framework_id/executors/:executor_id/tasks/:task_id/browse',
          {template: ' ', controller: 'AgentTaskAndExecutorRerouterCtrl'})
        .when('/agents/:agent_id/browse',
          {templateUrl: 'app/agents/agent-browse.html', controller: 'BrowseCtrl'})

        // TODO(tomxing): Remove the following '/slaves/*' paths once the
        // slave->agent rename is complete(MESOS-3779).
        .when('/slaves/:agent_id/frameworks/:framework_id/executors/:executor_id/browse',
          {redirectTo: '/agents/:agent_id/frameworks/:framework_id/executors/:executor_id/browse'})
        .when('/slaves/:agent_id/browse',
          {redirectTo: '/agents/:agent_id/browse'})
        .otherwise({redirectTo: '/'});

      // Configure [Angular UI Pagination][1]:
      //   * Show first/last buttons
      //   * Show 50 items per page
      //   * Show "..." when there are pages beyond the max shown
      //
      // [1] http://angular-ui.github.io/bootstrap/#/pagination
      paginationConfig.boundaryLinks = true;
      paginationConfig.rotate = false;
    }])
    .filter('truncateMesosID', function() {
      // Returns a truncated ID, for example:
      // Input: 9d4b2f2b-a759-4458-bebf-7d3507a6f0ca-S9
      // Output: ...7d3507a6f0ca-S9
      //
      // Note that an ellipsis is used for display purposes.
      return function(id) {
        if (id) {
          var truncatedIdParts = id.split('-');

          if (truncatedIdParts.length > 4) {
            return '\u2026' + truncatedIdParts.splice(4).join('-');
          } else {
            return id;
          }
        } else {
          return '';
        }
      };
    })
    .filter('truncateMesosState', function() {
      return function(state) {
        // Remove the "TASK_" prefix.
        return state.substring(5);
      };
    })
    .filter('taskHealth', function() {
      return function(healthy) {
        if (healthy == null) {
          return "-";
        }

        // Note that this string value is relied on to match
        // against CSS classes to color the UI. Changing this
        // also requires an update to the CSS.
        return healthy ? "healthy" : "unhealthy";
      }
    })
    .filter('isoDate', function($filter) {
      return function(date) {
        var i = parseInt(date, 10);
        if (_.isNaN(i)) { return '' }
        return $filter('date')(i, 'yyyy-MM-ddTHH:mm:ssZ');
      };
    })
    .filter('relativeDate', function() {
      return function(date, refDate) {
        var i = parseInt(date, 10);
        if (_.isNaN(i)) { return '' }
        return relativeDate(i, refDate);
      };
    })
    .filter('slice', function() {
      return function(array, begin, end) {
        if (_.isArray(array)) {
          return array.slice(begin, end);
        }
      };
    })
    .filter('unixDate', function($filter) {
      return function(date) {
        if ((new Date(date)).getFullYear() == (new Date()).getFullYear()) {
          return $filter('date')(date, 'MMM dd HH:mm');
        } else {
          return $filter('date')(date, 'MMM dd yyyy');
        }
      };
    })
    // A filter that uses to convert small float number to decimal string.
    .filter('decimalFloat', function() {
      return function(num) {
        return num ? parseFloat(num.toFixed(4)).toString() : num;
      }
    })
    .filter('dataSize', function() {
      var BYTES_PER_KB = Math.pow(2, 10);
      var BYTES_PER_MB = Math.pow(2, 20);
      var BYTES_PER_GB = Math.pow(2, 30);
      var BYTES_PER_TB = Math.pow(2, 40);
      var BYTES_PER_PB = Math.pow(2, 50);
      // NOTE: Number.MAX_SAFE_INTEGER is 2^53 - 1

      return function(bytes) {
        if (bytes == null || isNaN(bytes)) {
          return '';
        } else if (bytes < BYTES_PER_KB) {
          return bytes.toFixed() + ' B';
        } else if (bytes < BYTES_PER_MB) {
          return (bytes / BYTES_PER_KB).toFixed() + ' KB';
        } else if (bytes < BYTES_PER_GB) {
          return (bytes / BYTES_PER_MB).toFixed() + ' MB';
        } else if (bytes < BYTES_PER_TB) {
          return (bytes / BYTES_PER_GB).toFixed(1) + ' GB';
        } else if (bytes < BYTES_PER_PB) {
          return (bytes / BYTES_PER_TB).toFixed(1) + ' TB';
        } else {
          return (bytes / BYTES_PER_PB).toFixed(1) + ' PB';
        }
      };
    })
    .directive('clipboard', [function() {
      return {
        restrict: 'A',
        scope: true,
        template: '<i class="glyphicon glyphicon-file"></i>',

        link: function(scope, element, _attrs) {
          var clip = new Clipboard(element[0]);

          element.on('mouseenter', function() {
            element.addClass('clipboard-is-hover');
            element.triggerHandler('clipboardhover');
          });

          element.on('mouseleave', function() {
            // Restore tooltip content to its original value if it was
            // changed by this Clipboard instance.
            if (scope && scope.tt_content_orig) {
              scope.tt_content = scope.tt_content_orig;
              delete scope.tt_content_orig;
            }

            element.removeClass('clipboard-is-hover');
            element.triggerHandler('clipboardhover');
          });

          // Success for browsers with `execCommand` support.
          clip.on('success', function () {
            // Store the tooltip's original content so it can
            // be restored when the tooltip is hidden.
            scope.tt_content_orig = scope.tt_content;

            // Angular UI's Tooltip sets content on the element's scope in a
            // variable named 'tt_content'. The Tooltip has no public interface,
            // so set the value directly here to change the value of the tooltip
            // when content is successfully copied.
            scope.tt_content = 'Copied!';
            scope.$apply();
          });

          // Support for all other browsers without `execCommand`
          // support. Text will be selected and user will be prompted
          // to copy.
          clip.on('error', function() {
            scope.tt_content_orig = scope.tt_content;
            scope.tt_content = 'Press Ctrl/Cmd + C to copy!';
            scope.$apply();
          });
        }
      };
    }])
    .directive('mTimestamp', [ '$rootScope', function($rootScope) {
      return {
        restrict: 'E',
        transclude: true,
        scope: {
          value: '@'
        },
        link: function($scope, _element, _attrs) {
          $scope.longDate = JSON.parse(
            localStorage.getItem('longDate') || false);

          $scope.$on('mTimestamp.toggle', function() {
            $scope.longDate = !$scope.longDate;
          });

          $scope.toggle = function() {
            localStorage.setItem('longDate', !$scope.longDate);
            $rootScope.$broadcast('mTimestamp.toggle');
          };
        },
        templateUrl: 'app/shared/timestamp.html'
      }
    }])
    .directive('mPagination', function() {
      return { templateUrl: 'app/shared/pagination.html' }
    })
    .directive('mTableHeader', function() {
      return { templateUrl: 'app/shared/table-header.html' }
    })
    .directive('mTable', ['$compile', '$filter', function($compile, $filter) {
      /* This directive does not have a template. The DOM doesn't like
       * having partially defined tables and so they don't work well with
       * directives and templates. Because of this, the sub-elements that this
       * includes are their own directive/templates and it adds them via. DOM
       * manipulation here.
       */
      return {
        scope: true,
        link: function(scope, element, attrs) {
          var defaultOrder = true;

          _.extend(scope, {
            originalData: [],
            columnKey: '',
            sortOrder: defaultOrder,
            pgNum: 1,
            pageLength: 50,
            filterTerm: '',
            headerTitle: attrs.title
          })
          // ---

          // --- Allow sorting by column based on the <th> data-key attribute.
          // Does not apply for group columns as their children are sortable.
          var th = element.find('th').not('.group-column');
          th.attr('ng-click', 'sortColumn($event)');
          $compile(th)(scope);

          var setSorting = function(el) {
            var key = el.attr('data-key');

            // Prevent sorting when 'data-key' is undefined.
            if (!key) {
              return;
            }

            if (scope.columnKey === key) {
              scope.sortOrder = !scope.sortOrder;
            } else if (el.hasClass('ascending')) {
              // We can order the table the other way around by adding
              // 'class="ascending"' to the table header.
              scope.sortOrder = !defaultOrder;
            } else {
              scope.sortOrder = defaultOrder;
            }

            scope.columnKey = key;

            th.removeClass('descending ascending');
            el.addClass(scope.sortOrder ? 'descending' : 'ascending');
          };

          var defaultSortColumn = function() {
            var el = element.find('[data-sort]');
            if (el.length === 0) {
              el = element.find('th:first');
            }
            return el;
          };

          scope.sortColumn = function(ev) {
            setSorting(angular.element(ev.target));
          };

          setSorting(defaultSortColumn());
          // ---

          scope.$watch(attrs.tableContent, function(data) {
            if (!data) { scope.originalData = []; return }
            if (angular.isObject(data)) { data = _.values(data) }

            scope.originalData = data;
          });

          var setTableData = function() {
            scope.filteredData = $filter('filter')(scope.originalData, scope.filterTerm)
            scope.$data = $filter('orderBy')(
              scope.filteredData,
              scope.columnKey,
              scope.sortOrder).slice(
                (scope.pgNum - 1) * scope.pageLength,
                scope.pgNum * scope.pageLength);
          };

          // Reset the page number for each new filtering.
          scope.$watch('filterTerm', function() { scope.pgNum = 1; });

          _.each(['originalData', 'columnKey', 'sortOrder', 'pgNum', 'filterTerm'],
            function(k) { scope.$watch(k, setTableData); });

          // --- Pagination controls
          var el = angular.element('<div m-pagination></div>');
          $compile(el)(scope);
          element.after(el);
          // ---

          // --- Filtering
          el = angular.element('<div m-table-header></div>');
          $compile(el)(scope);
          element.before(el);
          // ---
        }
      };
     }]);
})();
