// 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';

  var mesosApp = angular.module('mesos');

  function hasSelectedText() {
    if (window.getSelection) {  // All browsers except IE before version 9.
      var range = window.getSelection();
      return range.toString().length > 0;
    }
    return false;
  }

  // Returns the URL prefix for an agent, there are two cases
  // to consider:
  //
  //   (1) Some endpoints for the agent process itself require
  //       the agent PID.name (processId) in the path, this is
  //       to ensure that the webui works correctly when running
  //       against mesos-local or other instances of multiple agents
  //       running within the same "host:port":
  //
  //         //hostname:port/slave(1)
  //         //hostname:port/slave(2)
  //         ...
  //
  //   (2) Some endpoints for other components in the agent
  //       do not require the agent PID.name in the path, since
  //       a single endpoint serves multiple agents within the
  //       same process. In this case we just return:
  //
  //         //hostname:port
  //
  // Note that there are some clashing issues in mesos-local
  // (e.g., hosting '/slave/log' for each agent log, we don't
  // namespace metrics within '/metrics/snapshot', etc).
  function agentURLPrefix(agent, includeProcessId) {
    var port = agent.pid.substring(agent.pid.lastIndexOf(':') + 1);
    var processId = agent.pid.substring(0, agent.pid.indexOf('@'));

    var url = '//' + agent.hostname + ':' + port;

    if (includeProcessId) {
      url += '/' + processId;
    }

    return url;
  }

  function leadingMasterURLPrefix(leader_info) {
    if (leader_info) {
      return '//' + leader_info.hostname + ':' + leader_info.port;
    }

    // If we do not have `leader_info` available (e.g. the first
    // time we are retrieving state), fallback to the current master.
    return '';
  }

  // Invokes the pailer, building the endpoint URL with the specified urlPrefix
  // and path.
  function pailer(urlPrefix, path, window_title) {
    var url = urlPrefix + '/files/read?path=' + path;

    // The randomized `storageKey` is removed from `localStorage` once the
    // pailer window loads the URL into its `sessionStorage`, therefore
    // the probability of collisions is low and we do not use a uuid.
    var storageKey = Math.random().toString(36).substr(2, 8);

    // Store the target URL in `localStorage` which is
    // accessed by the pailer window when opened.
    localStorage.setItem(storageKey, url);

    var pailer =
      window.open('app/shared/pailer.html', storageKey, 'width=580px, height=700px');

    // Need to use window.onload instead of document.ready to make
    // sure the title doesn't get overwritten.
    pailer.onload = function() {
      pailer.document.title = window_title;
    };
  }


  function updateInterval(num_agents) {
    // TODO(bmahler): Increasing the update interval for large clusters
    // is done purely to mitigate webui performance issues. Ideally we can
    // keep a consistently fast rate for updating statistical information.
    // For the full system state updates, it may make sense to break
    // it up using pagination and/or splitting the endpoint.
    if (num_agents < 500) {
      return 10000;
    } else if (num_agents < 1000) {
      return 20000;
    } else if (num_agents < 5000) {
      return 60000;
    } else if (num_agents < 10000) {
      return 120000;
    } else if (num_agents < 15000) {
      return 240000;
    } else if (num_agents < 20000) {
      return 480000;
    } else {
      return 960000;
    }
  }

  // Set the task sandbox directory for use by the WebUI.
  function setTaskSandbox(executor) {
    _.each(
        [executor.tasks, executor.queued_tasks, executor.completed_tasks],
        function(tasks) {
      _.each(tasks, function(task) {
        if (executor.type === 'DEFAULT') {
          task.directory = executor.directory + '/tasks/' + task.id;
        } else {
          task.directory = executor.directory;
        }
      });
    });
  }


  // Update the outermost scope with the new state.
  function updateState($scope, $timeout, state) {
    // Don't do anything if the state hasn't changed.
    if ($scope.state == state) {
      return true; // Continue polling.
    }

    $scope.state = state;

    // A cluster is named if the state returns a non-empty string name.
    // Track whether this cluster is named in a Boolean for display purposes.
    $scope.clusterNamed = !!$scope.state.cluster;

    // Check for selected text, and allow up to 20 seconds to pass before
    // potentially wiping the user highlighted text.
    // TODO(bmahler): This is to avoid the annoying loss of highlighting when
    // the tables update. Once we can have tighter granularity control on the
    // angular.js dynamic table updates, we should remove this hack.
    $scope.time_since_update += $scope.delay;

    if (hasSelectedText() && $scope.time_since_update < 20000) {
      return true;
    }

    // Pass this pollTime to all relativeDate calls to make them all relative to
    // the same moment in time.
    //
    // If relativeDate is called without a reference time, it instantiates a new
    // Date to be the reference. Since there can be hundreds of dates on a given
    // page, they would all be relative to slightly different moments in time.
    $scope.pollTime = new Date();

    // Update the maps.
    $scope.agents = {};
    $scope.frameworks = {};
    $scope.offers = {};
    $scope.completed_frameworks = {};
    $scope.active_tasks = [];
    $scope.unreachable_tasks = [];
    $scope.completed_tasks = [];

    // Update the stats.
    $scope.cluster = $scope.state.cluster;
    $scope.total_cpus = 0;
    $scope.total_gpus = 0;
    $scope.total_mem = 0;
    $scope.total_disk = 0;
    $scope.used_cpus = 0;
    $scope.used_gpus = 0;
    $scope.used_mem = 0;
    $scope.used_disk = 0;
    $scope.offered_cpus = 0;
    $scope.offered_gpus = 0;
    $scope.offered_mem = 0;
    $scope.offered_disk = 0;

    $scope.activated_agents = $scope.state.activated_slaves;
    $scope.deactivated_agents = $scope.state.deactivated_slaves;
    $scope.unreachable_agents = $scope.state.unreachable_slaves;

    _.each($scope.state.slaves, function(agent) {
      $scope.agents[agent.id] = agent;
      $scope.total_cpus += agent.resources.cpus;
      $scope.total_gpus += agent.resources.gpus;
      $scope.total_mem += agent.resources.mem;
      $scope.total_disk += agent.resources.disk;
    });

    var setTaskMetadata = function(task) {
      if (!task.executor_id) {
        task.executor_id = task.id;
      }
      if (task.statuses.length > 0) {
          var firstStatus = task.statuses[0];
          if (!isStateTerminal(firstStatus.state)) {
              task.start_time = firstStatus.timestamp * 1000;
          }
          var lastStatus = task.statuses[task.statuses.length - 1];
          if (isStateTerminal(task.state)) {
              task.finish_time = lastStatus.timestamp * 1000;
          }
          task.healthy = lastStatus.healthy;
      }
    };

    var isStateTerminal = function(taskState) {
      var terminalStates = [
          'TASK_ERROR',
          'TASK_FAILED',
          'TASK_FINISHED',
          'TASK_KILLED',
          'TASK_LOST',
          'TASK_DROPPED',
          'TASK_GONE',
          'TASK_GONE_BY_OPERATOR'
      ];
      return terminalStates.indexOf(taskState) > -1;
    };

    _.each($scope.state.frameworks, function(framework) {
      $scope.frameworks[framework.id] = framework;

      // Fill in the `roles` field for non-MULTI_ROLE schedulers.
      if (framework.role) {
        framework.roles = [framework.role];
      }

      _.each(framework.offers, function(offer) {
        $scope.offers[offer.id] = offer;
        $scope.offered_cpus += offer.resources.cpus;
        $scope.offered_gpus += offer.resources.gpus;
        $scope.offered_mem += offer.resources.mem;
        $scope.offered_disk += offer.resources.disk;
        offer.framework_name = $scope.frameworks[offer.framework_id].name;
        offer.hostname = $scope.agents[offer.slave_id].hostname;
      });

      $scope.used_cpus += framework.resources.cpus;
      $scope.used_gpus += framework.resources.gpus;
      $scope.used_mem += framework.resources.mem;
      $scope.used_disk += framework.resources.disk;

      framework.cpus_share = 0;
      if ($scope.total_cpus > 0) {
        framework.cpus_share = framework.used_resources.cpus / $scope.total_cpus;
      }

      framework.gpus_share = 0;
      if ($scope.total_gpus > 0) {
        framework.gpus_share = framework.used_resources.gpus / $scope.total_gpus;
      }

      framework.mem_share = 0;
      if ($scope.total_mem > 0) {
        framework.mem_share = framework.used_resources.mem / $scope.total_mem;
      }

      framework.disk_share = 0;
      if ($scope.total_disk > 0) {
        framework.disk_share = framework.used_resources.disk / $scope.total_disk;
      }

      framework.max_share = Math.max(
          framework.cpus_share,
          framework.gpus_share,
          framework.mem_share,
          framework.disk_share);

      // If the executor ID is empty, this is a command executor with an
      // internal executor ID generated from the task ID.
      // TODO(brenden): Remove this once
      // https://issues.apache.org/jira/browse/MESOS-527 is fixed.
      _.each(framework.tasks, setTaskMetadata);
      _.each(framework.unreachable_tasks, setTaskMetadata);
      _.each(framework.completed_tasks, setTaskMetadata);

      // TODO(bmahler): Add per-framework metrics to the master so that
      // the webui does not need to loop over all tasks!
      framework.running_tasks = 0;
      framework.staging_tasks = 0;
      framework.starting_tasks = 0;
      framework.killing_tasks = 0;

      _.each(framework.tasks, function(task) {
        switch (task.state) {
            case "TASK_STAGING": framework.staging_tasks += 1; break;
            case "TASK_STARTING": framework.starting_tasks += 1; break;
            case "TASK_RUNNING": framework.running_tasks += 1; break;
            case "TASK_KILLING": framework.killing_tasks += 1; break;
            default: break;
        }
      })

      framework.finished_tasks = 0;
      framework.killed_tasks = 0;
      framework.failed_tasks = 0;
      framework.lost_tasks = 0;

      _.each(framework.completed_tasks, function(task) {
        switch (task.state) {
            case "TASK_FINISHED": framework.finished_tasks += 1; break;
            case "TASK_KILLED": framework.killed_tasks += 1; break;
            case "TASK_FAILED": framework.failed_tasks += 1; break;
            case "TASK_LOST": framework.lost_tasks += 1; break;
            default: break;
        }
      })

      $scope.active_tasks = $scope.active_tasks.concat(framework.tasks);
      $scope.unreachable_tasks = $scope.unreachable_tasks.concat(framework.unreachable_tasks);
      $scope.completed_tasks =
        $scope.completed_tasks.concat(framework.completed_tasks);
    });

    _.each($scope.state.completed_frameworks, function(framework) {
      $scope.completed_frameworks[framework.id] = framework;

      // Fill in the `roles` field for non-MULTI_ROLE schedulers.
      if (framework.role) {
        framework.roles = [framework.role];
      }

      _.each(framework.completed_tasks, setTaskMetadata);
    });

    $scope.used_cpus -= $scope.offered_cpus;
    $scope.used_gpus -= $scope.offered_gpus;
    $scope.used_mem -= $scope.offered_mem;
    $scope.used_disk -= $scope.offered_disk;

    $scope.idle_cpus = $scope.total_cpus - ($scope.offered_cpus + $scope.used_cpus);
    $scope.idle_gpus = $scope.total_gpus - ($scope.offered_gpus + $scope.used_gpus);
    $scope.idle_mem = $scope.total_mem - ($scope.offered_mem + $scope.used_mem);
    $scope.idle_disk = $scope.total_disk - ($scope.offered_disk + $scope.used_disk);

    $scope.time_since_update = 0;
    $scope.$broadcast('state_updated');

    return true; // Continue polling.
  }

  // Update the outermost scope with the metrics/snapshot endpoint.
  function updateMetrics($scope, $timeout, metrics) {
    $scope.staging_tasks = metrics['master/tasks_staging'];
    $scope.starting_tasks = metrics['master/tasks_starting'];
    $scope.running_tasks = metrics['master/tasks_running'];
    $scope.killing_tasks = metrics['master/tasks_killing'];
    $scope.finished_tasks = metrics['master/tasks_finished'];
    $scope.killed_tasks = metrics['master/tasks_killed'];
    $scope.failed_tasks = metrics['master/tasks_failed'];
    $scope.lost_tasks = metrics['master/tasks_lost'];

    return true; // Continue polling.
  }


  // Main controller that can be used to handle "global" events. E.g.,:
  //     $scope.$on('$afterRouteChange', function() { ...; });
  //
  // In addition, the MainCtrl encapsulates the "view", allowing the
  // active controller/view to easily access anything in scope (e.g.,
  // the state).
  mesosApp.controller('MainCtrl', [
      '$scope', '$http', '$location', '$timeout', '$modal',
      function($scope, $http, $location, $timeout, $modal) {
    $scope.doneLoading = true;

    // Adding bindings into scope so that they can be used from within
    // AngularJS expressions.
    $scope._ = _;
    $scope.stringify = JSON.stringify;
    $scope.encodeURIComponent = encodeURIComponent;
    $scope.basename = function(path) {
      // This is only a basic version of basename that handles the cases we care
      // about, rather than duplicating unix basename functionality perfectly.
      if (path === '/') {
        return path;  // Handle '/'.
      }

      // Strip a trailing '/' if present.
      if (path.length > 0 && path.lastIndexOf('/') === (path.length - 1)) {
        path = path.substr(0, path.length - 1);
      }
      return path.substr(path.lastIndexOf('/') + 1);
    };

    $scope.$location = $location;
    $scope.delay = 2000;
    $scope.retry = 0;
    $scope.time_since_update = 0;
    $scope.isErrorModalOpen = false;

    // Ordered Array of path => activeTab mappings. On successful route changes,
    // the `pathRegexp` values are matched against the current route. The first
    // match will be used to set the active navbar tab.
    var NAVBAR_PATHS = [
      {
        pathRegexp: /^\/agents/,
        tab: 'agents'
      },
      {
        pathRegexp: /^\/frameworks/,
        tab: 'frameworks'
      },
      {
        pathRegexp: /^\/roles/,
        tab: 'roles'
      },
      {
        pathRegexp: /^\/offers/,
        tab: 'offers'
      },
      {
        pathRegexp: /^\/maintenance/,
        tab: 'maintenance'
      }
    ];

    // Set the active tab on route changes according to NAVBAR_PATHS.
    $scope.$on('$routeChangeSuccess', function(event, current) {
      var path = current.$$route.originalPath;

      // Use _.some so the loop can exit on the first `pathRegexp` match.
      var matched = _.some(NAVBAR_PATHS, function(nav) {
        if (path.match(nav.pathRegexp)) {
          $scope.navbarActiveTab = nav.tab;
          return true;
        }
      });

      if (!matched) $scope.navbarActiveTab = null;
    });

    var popupErrorModal = function() {
      if ($scope.delay >= 128000) {
        $scope.delay = 2000;
      } else {
        $scope.delay = $scope.delay * 2;
      }

      $scope.isErrorModalOpen = true;

      var errorModal = $modal.open({
        controller: function($scope, $modalInstance, scope) {
          // Give the modal reference to the root scope so it can access the
          // `retry` variable. It needs to be passed by reference, not by
          // value, since its value is changed outside the scope of the
          // modal.
          $scope.rootScope = scope;
        },
        resolve: {
          scope: function() { return $scope; }
        },
        templateUrl: "template/dialog/master-gone.html"
      });

      // Make it such that everytime we hide the error-modal, we stop the
      // countdown and restart the polling.
      errorModal.result.then(function() {
        $scope.isErrorModalOpen = false;

        if ($scope.countdown != null) {
          if ($timeout.cancel($scope.countdown)) {
            // Restart since they cancelled the countdown.
            $scope.delay = 2000;
          }
        }

        // Start polling again, but do it asynchronously (and wait at
        // least a second because otherwise the error-modal won't get
        // properly shown).
        $timeout(pollState, 1000);
        $timeout(pollMetrics, 1000);
      });

      $scope.retry = $scope.delay;
      var countdown = function() {
        if ($scope.retry === 0) {
          errorModal.close();
        } else {
          $scope.retry = $scope.retry - 1000;
          $scope.countdown = $timeout(countdown, 1000);
        }
      };
      countdown();
    };

    var pollState = function() {
      // When the current master is not the leader, the request is redirected to
      // the leading master automatically. This would cause a CORS error if we
      // use XMLHttpRequest here. To avoid the CORS error, we use JSONP as a
      // workaround. Please refer to MESOS-5911 for further details.
      //
      // Note that `$scope.state` will not be defined during the first
      // request.
      var leader_info = $scope.state ? $scope.state.leader_info : null;

      $http.jsonp(leadingMasterURLPrefix(leader_info) +
                  '/master/state?jsonp=JSON_CALLBACK')
        .success(function(response) {
          if (updateState($scope, $timeout, response)) {
            $scope.delay = updateInterval(_.size($scope.agents));
            $timeout(pollState, $scope.delay);
          }
        })
        .error(function() {
          if ($scope.isErrorModalOpen === false) {
            popupErrorModal();
          }
        });
    };

    var pollMetrics = function() {
      var leader_info = $scope.state ? $scope.state.leader_info : null;

      $http.jsonp(leadingMasterURLPrefix(leader_info) +
                  '/metrics/snapshot?jsonp=JSON_CALLBACK')
        .success(function(response) {
          if (updateMetrics($scope, $timeout, response)) {
            $scope.delay = updateInterval(_.size($scope.agents));
            $timeout(pollMetrics, $scope.delay);
          }
        })
        .error(function(message, code) {
          if ($scope.isErrorModalOpen === false) {
            // If return code is 401 or 403 the user is unauthorized to reach
            // the endpoint, which is not a connection error.
            if ([401, 403].indexOf(code) < 0) {
              popupErrorModal();
            }
          }
        });
    };

    pollState();
    pollMetrics();
  }]);

  mesosApp.controller('HomeCtrl', function($scope) {
    var hostname = $scope.$location.host() + ':' + $scope.$location.port();

    var update = function() {
      $scope.streamLogs = function(_$event) {
        pailer(
            leadingMasterURLPrefix($scope.state.leader_info),
            '/master/log',
            'Mesos Master (' + hostname + ')');
      };

      // Note that we always show the leader's log, which is why
      // we examine the leader's flags to determine whether the
      // log file is attached.
      $scope.log_file_attached =
        $scope.state.flags.external_log_file || $scope.state.flags.log_dir;

      $scope.leader_url_prefix =
        leadingMasterURLPrefix($scope.state.leader_info);
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  });

  mesosApp.controller('FrameworksCtrl', function() {});

  mesosApp.controller('RolesCtrl', function($scope, $http) {
    var update = function() {
      $http.jsonp(leadingMasterURLPrefix($scope.state.leader_info) +
                  '/master/roles?jsonp=JSON_CALLBACK')
      .success(function(response) {
        $scope.roles = response;
      })
      .error(function() {
        if ($scope.isErrorModalOpen === false) {
          popupErrorModal();
        }
      });
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  });

  mesosApp.controller('OffersCtrl', function() {});

  mesosApp.controller('MaintenanceCtrl', function($scope, $http) {
    var update = function() {
      $http.jsonp(leadingMasterURLPrefix($scope.state.leader_info) +
                  '/master/maintenance/schedule?jsonp=JSON_CALLBACK')
      .success(function(response) {
        $scope.maintenance = response;
      })
      .error(function() {
        if ($scope.isErrorModalOpen === false) {
          popupErrorModal();
        }
      });
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  });

  mesosApp.controller('FrameworkCtrl', function($scope, $routeParams) {
    var update = function() {
      if ($routeParams.id in $scope.completed_frameworks) {
        $scope.framework = $scope.completed_frameworks[$routeParams.id];
        $scope.alert_message = 'This framework has terminated!';
        $('#alert').show();
        $('#framework').show();
      } else if ($routeParams.id in $scope.frameworks) {
        $scope.framework = $scope.frameworks[$routeParams.id];
        $('#framework').show();
      } else {
        $scope.alert_message = 'No framework found with ID: ' + $routeParams.id;
        $('#alert').show();
      }
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  });


  mesosApp.controller('AgentsCtrl', function() {});


  mesosApp.controller('AgentCtrl', [
      '$scope', '$routeParams', '$http', '$q', '$timeout', 'top',
      function($scope, $routeParams, $http, $q, $timeout, $top) {
    $scope.agent_id = $routeParams.agent_id;

    var update = function() {
      if (!($routeParams.agent_id in $scope.agents)) {
        $scope.alert_message = 'No agent found with ID: ' + $routeParams.agent_id;
        $('#alert').show();
        return;
      }

      var agent = $scope.agents[$routeParams.agent_id];

      $scope.streamLogs = function(_$event) {
        pailer(agentURLPrefix(agent, false), '/slave/log', 'Mesos Agent (' + agent.id + ')');
      };


      // Set up polling for the monitor if this is the first update.
      if (!$top.started()) {
        $top.start(
          agentURLPrefix(agent, true) + '/monitor/statistics?jsonp=JSON_CALLBACK',
          $scope
        );
      }

      $http.jsonp(agentURLPrefix(agent, true) + '/state?jsonp=JSON_CALLBACK')
        .success(function (response) {
          $scope.state = response;

          $scope.agent = {};
          $scope.agent.frameworks = {};
          $scope.agent.completed_frameworks = {};
          $scope.agent.url_prefix = agentURLPrefix(agent, false);

          // The agent attaches a "/slave/log" file when either
          // of these flags are set.
          $scope.agent.log_file_attached = $scope.state.external_log_file || $scope.state.log_dir;

          // Convert the reserved resources map into an array for inclusion
          // in an `ng-repeat` table.
          $scope.agent.reserved_resources_as_array = _($scope.state.reserved_resources)
            .map(function(reservation, role) {
              reservation.role = role;
              return reservation;
            });

          // Computes framework stats by setting new attributes on the 'framework'
          // object.
          function computeFrameworkStats(framework) {
            framework.num_tasks = 0;
            framework.cpus = 0;
            framework.gpus = 0;
            framework.mem = 0;
            framework.disk = 0;

            _.each(framework.executors, function(executor) {
              framework.num_tasks += _.size(executor.tasks);
              framework.cpus += executor.resources.cpus;
              framework.gpus += executor.resources.gpus;
              framework.mem += executor.resources.mem;
              framework.disk += executor.resources.disk;
            });
          }

          // Compute framework stats and update agent's mappings of those
          // frameworks.
          _.each($scope.state.frameworks, function(framework) {
            $scope.agent.frameworks[framework.id] = framework;
            computeFrameworkStats(framework);

            // Fill in the `roles` field for non-MULTI_ROLE schedulers.
            if (framework.role) {
              framework.roles = [framework.role];
            }
          });

          _.each($scope.state.completed_frameworks, function(framework) {
            $scope.agent.completed_frameworks[framework.id] = framework;
            computeFrameworkStats(framework);

            // Fill in the `roles` field for non-MULTI_ROLE schedulers.
            if (framework.role) {
              framework.roles = [framework.role];
            }
          });

          $scope.state.allocated_resources = {};
          $scope.state.allocated_resources.cpus = 0;
          $scope.state.allocated_resources.gpus = 0;
          $scope.state.allocated_resources.mem = 0;
          $scope.state.allocated_resources.disk = 0;

          // Currently the agent does not expose the total allocated
          // resources across all frameworks, so we sum manually.
          _.each($scope.state.frameworks, function(framework) {
            $scope.state.allocated_resources.cpus += framework.cpus;
            $scope.state.allocated_resources.gpus += framework.gpus;
            $scope.state.allocated_resources.mem += framework.mem;
            $scope.state.allocated_resources.disk += framework.disk;
          });

          $('#agent').show();
        })
        .error(function(reason) {
          $scope.alert_message = 'Failed to get agent usage / state: ' + reason;
          $('#alert').show();
        });

      $http.jsonp(agentURLPrefix(agent, false) + '/metrics/snapshot?jsonp=JSON_CALLBACK')
        .success(function (response) {
          $scope.staging_tasks = response['slave/tasks_staging'];
          $scope.starting_tasks = response['slave/tasks_starting'];
          $scope.running_tasks = response['slave/tasks_running'];
          $scope.killing_tasks = response['slave/tasks_killing'];
          $scope.finished_tasks = response['slave/tasks_finished'];
          $scope.killed_tasks = response['slave/tasks_killed'];
          $scope.failed_tasks = response['slave/tasks_failed'];
          $scope.lost_tasks = response['slave/tasks_lost'];
        })
        .error(function(reason) {
          $scope.alert_message = 'Failed to get agent metrics: ' + reason;
          $('#alert').show();
        });
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  }]);


  mesosApp.controller('AgentFrameworkCtrl', [
      '$scope', '$routeParams', '$http', '$q', '$timeout', 'top',
      function($scope, $routeParams, $http, $q, $timeout, $top) {
    $scope.agent_id = $routeParams.agent_id;
    $scope.framework_id = $routeParams.framework_id;

    var update = function() {
      if (!($routeParams.agent_id in $scope.agents)) {
        $scope.alert_message = 'No agent found with ID: ' + $routeParams.agent_id;
        $('#alert').show();
        return;
      }

      var agent = $scope.agents[$routeParams.agent_id];

      // Set up polling for the monitor if this is the first update.
      if (!$top.started()) {
        $top.start(
          agentURLPrefix(agent, true) + '/monitor/statistics?jsonp=JSON_CALLBACK',
          $scope
        );
      }

      $http.jsonp(agentURLPrefix(agent, true) + '/state?jsonp=JSON_CALLBACK')
        .success(function (response) {
          $scope.state = response;

          $scope.agent = {};

          function matchFramework(framework) {
            return $scope.framework_id === framework.id;
          }

          // Find the framework; it's either active or completed.
          $scope.framework =
              _.find($scope.state.frameworks, matchFramework) ||
              _.find($scope.state.completed_frameworks, matchFramework);

          if (!$scope.framework) {
            $scope.alert_message = 'No framework found with ID: ' + $routeParams.framework_id;
            $('#alert').show();
            return;
          }

          // Fill in the `roles` field for non-MULTI_ROLE schedulers.
          if ($scope.framework.role) {
            $scope.framework.roles = [$scope.framework.role];
          }

          // Compute the framework stats.
          $scope.framework.num_tasks = 0;
          $scope.framework.cpus = 0;
          $scope.framework.gpus = 0;
          $scope.framework.mem = 0;
          $scope.framework.disk = 0;

          _.each($scope.framework.executors, function(executor) {
            $scope.framework.num_tasks += _.size(executor.tasks);
            $scope.framework.cpus += executor.resources.cpus;
            $scope.framework.gpus += executor.resources.gpus;
            $scope.framework.mem += executor.resources.mem;
            $scope.framework.disk += executor.resources.disk;

            // If 'role' is not present in executor, we are talking
            // to a non-MULTI_ROLE capable agent. This means that we
            // can use the 'role' of the framework.
            executor.role = executor.role || $scope.framework.role;
          });

          $('#agent').show();
        })
        .error(function (reason) {
          $scope.alert_message = 'Failed to get agent usage / state: ' + reason;
          $('#alert').show();
        });
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  }]);


  mesosApp.controller('AgentExecutorCtrl', [
      '$scope', '$routeParams', '$http', '$q', '$timeout', 'top',
      function($scope, $routeParams, $http, $q, $timeout, $top) {
    $scope.agent_id = $routeParams.agent_id;
    $scope.framework_id = $routeParams.framework_id;
    $scope.executor_id = $routeParams.executor_id;

    var update = function() {
      if (!($routeParams.agent_id in $scope.agents)) {
        $scope.alert_message = 'No agent found with ID: ' + $routeParams.agent_id;
        $('#alert').show();
        return;
      }

      var agent = $scope.agents[$routeParams.agent_id];

      // Set up polling for the monitor if this is the first update.
      if (!$top.started()) {
        $top.start(
          agentURLPrefix(agent, true) + '/monitor/statistics?jsonp=JSON_CALLBACK',
          $scope
        );
      }

      $http.jsonp(agentURLPrefix(agent, true) + '/state?jsonp=JSON_CALLBACK')
        .success(function (response) {
          $scope.state = response;

          $scope.agent = {};

          function matchFramework(framework) {
            return $scope.framework_id === framework.id;
          }

          // Find the framework; it's either active or completed.
          $scope.framework =
            _.find($scope.state.frameworks, matchFramework) ||
            _.find($scope.state.completed_frameworks, matchFramework);

          if (!$scope.framework) {
            $scope.alert_message = 'No framework found with ID: ' + $routeParams.framework_id;
            $('#alert').show();
            return;
          }

          function matchExecutor(executor) {
            return $scope.executor_id === executor.id;
          }

          function setRole(tasks) {
            _.each(tasks, function(task) {
              task.role = $scope.framework.role;
            });
          }

          function setHealth(tasks) {
            _.each(tasks, function(task) {
              var lastStatus = _.last(task.statuses);
              if (lastStatus) {
                task.healthy = lastStatus.healthy;
              }
            })
          }

          // Look for the executor; it's either active or completed.
          $scope.executor =
            _.find($scope.framework.executors, matchExecutor) ||
            _.find($scope.framework.completed_executors, matchExecutor);

          if (!$scope.executor) {
            $scope.alert_message = 'No executor found with ID: ' + $routeParams.executor_id;
            $('#alert').show();
            return;
          }

          // If 'role' is not present in the task, we are talking
          // to a non-MULTI_ROLE capable agent. This means that we
          // can use the 'role' of the framework.
          if (!("role" in $scope.executor)) {
            $scope.executor.role = $scope.framework.role;

            setRole($scope.executor.tasks);
            setRole($scope.executor.queued_tasks);
            setRole($scope.executor.completed_tasks);
          }

          setHealth($scope.executor.tasks);
          setTaskSandbox($scope.executor);

          $('#agent').show();
        })
        .error(function (reason) {
          $scope.alert_message = 'Failed to get agent usage / state: ' + reason;
          $('#alert').show();
        });
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  }]);


  // Reroutes requests like:
  //   * '/agents/:agent_id/frameworks/:framework_id/executors/:executor_id/browse'
  //   * '/agents/:agent_id/frameworks/:framework_id/executors/:executor_id/tasks/:task_id/browse'
  // to the sandbox directory of the executor or the task respectively. This
  // requires a second request because the directory to browse is known by the
  // agent but not by the master. Request the directory from the agent, and then
  // redirect to it.
  //
  // TODO(ssorallen): Add `executor.directory` to the master's state endpoint
  // output so this controller of rerouting is no longer necessary.
  mesosApp.controller('AgentTaskAndExecutorRerouterCtrl',
      function($alert, $http, $location, $routeParams, $scope, $window) {

    function goBack(flashMessageOrOptions) {
      if (flashMessageOrOptions) {
        $alert.danger(flashMessageOrOptions);
      }

      if ($window.history.length > 1) {
        // If the browser has something in its history, just go back.
        $window.history.back();
      } else {
        // Otherwise navigate to the framework page, which is likely the
        // previous page anyway.
        $location.path('/frameworks/' + $routeParams.framework_id).replace();
      }
    }

    var reroute = function() {
      var agent = $scope.agents[$routeParams.agent_id];

      // If the agent doesn't exist, send the user back.
      if (!agent) {
        return goBack("Agent with ID '" + $routeParams.agent_id + "' does not exist.");
      }

      // Request agent details to get access to the route executor's "directory"
      // to navigate directly to the executor's sandbox.
      var url = agentURLPrefix(agent, true) + '/state?jsonp=JSON_CALLBACK';
      $http.jsonp(url)
        .success(function(response) {

          function matchFramework(framework) {
            return $routeParams.framework_id === framework.id;
          }

          var framework =
            _.find(response.frameworks, matchFramework) ||
            _.find(response.completed_frameworks, matchFramework);

          if (!framework) {
            return goBack(
              "Framework with ID '" + $routeParams.framework_id +
                "' does not exist on agent with ID '" + $routeParams.agent_id +
                "'."
            );
          }

          function matchExecutor(executor) {
            return $routeParams.executor_id === executor.id;
          }

          var executor =
            _.find(framework.executors, matchExecutor) ||
            _.find(framework.completed_executors, matchExecutor);

          if (!executor) {
            return goBack(
              "Executor with ID '" + $routeParams.executor_id +
                "' does not exist on agent with ID '" + $routeParams.agent_id +
                "'."
            );
          }

          var sandboxDirectory = executor.directory;

          function matchTask(task) {
            return $routeParams.task_id === task.id;
          }

          // Continue to navigate to the task's sandbox if the task id is
          // specified in route parameters.
          if ($routeParams.task_id) {
            setTaskSandbox(executor);

            var task =
              _.find(executor.tasks, matchTask) ||
              _.find(executor.queued_tasks, matchTask) ||
              _.find(executor.completed_tasks, matchTask);

            if (!task) {
              return goBack(
                "Task with ID '" + $routeParams.task_id +
                  "' does not exist on agent with ID '" + $routeParams.agent_id +
                  "'."
              );
            }

            sandboxDirectory = task.directory;
          }

          // Navigate to a path like '/agents/:id/browse?path=%2Ftmp%2F', the
          // recognized "browse" endpoint for an agent.
          $location.path('/agents/' + $routeParams.agent_id + '/browse')
            .search({path: sandboxDirectory})
            .replace();
        })
        .error(function(_response) {
          $alert.danger({
            bullets: [
             "The agent is not accessible",
             "The agent timed out or went offline"
            ],
            message: "Potential reasons:",
            title: "Failed to connect to agent '" + $routeParams.agent_id +
              "' on '" + url + "'."
          });

          // Is the agent dead? Navigate home since returning to the agent might
          // end up in an endless loop.
          $location.path('/').replace();
        });
    };

    // When navigating directly to this page, e.g. pasting the URL into the
    // browser, the previous page is not a page in Mesos. The agents
    // information may not ready when loading this page, we start to reroute
    // the sandbox request after the agents information loaded.
    if ($scope.state) {
      reroute();
    }

    // `reroute` is expected to always route away from the current page
    // and the listener would be removed after the first state update.
    var removeListener = $scope.$on('state_updated', reroute);
    $scope.$on('$routeChangeStart', removeListener);
  });


  mesosApp.controller('BrowseCtrl', function($scope, $routeParams, $http) {
    var update = function() {
      if ($routeParams.agent_id in $scope.agents && $routeParams.path) {
        $scope.agent_id = $routeParams.agent_id;
        $scope.path = $routeParams.path;

        var agent = $scope.agents[$routeParams.agent_id];

        // This variable is used in 'browse.html' to generate the '/files'
        // links, so we have to pass `includeProcessId=false` (see
        // `agentURLPrefix`for more details).
        $scope.agent_url_prefix = agentURLPrefix(agent, false);

        $scope.pail = function($event, path) {
          pailer(
            agentURLPrefix(agent, false),
            path,
            decodeURIComponent(path) + ' (' + agent.id + ')');
        };

        var url = agentURLPrefix(agent, false) + '/files/browse?jsonp=JSON_CALLBACK';

        // TODO(bmahler): Try to get the error code / body in the error callback.
        // This wasn't working with the current version of angular.
        $http.jsonp(url, {params: {path: $routeParams.path}})
          .success(function(data) {
            $scope.listing = data;
            $('#listing').show();
          })
          .error(function() {
            $scope.alert_message = 'Error browsing path: ' + $routeParams.path;
            $('#alert').show();
          });
      } else {
        if (!($routeParams.agent_id in $scope.agents)) {
          $scope.alert_message = 'No agent found with ID: ' + $routeParams.agent_id;
        } else {
          $scope.alert_message = 'Missing "path" request parameter.';
        }
        $('#alert').show();
      }
    };

    if ($scope.state) {
      update();
    }

    var removeListener = $scope.$on('state_updated', update);
    $scope.$on('$routeChangeStart', removeListener);
  });
})();
