/**
 * Controller for firmware
 *
 * @module app/configuration
 * @exports firmwareController
 * @name firmwareController
 */

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

  angular.module('app.configuration').controller('firmwareController', [
    '$scope', '$window', 'APIUtils', 'dataService', '$location',
    '$anchorScroll', 'Constants', '$interval', '$q', '$timeout', '$interpolate',
    function(
        $scope, $window, APIUtils, dataService, $location, $anchorScroll,
        Constants, $interval, $q, $timeout, $interpolate) {
      $scope.dataService = dataService;

      // Scroll to target anchor
      $scope.gotoAnchor = function() {
        $location.hash('upload');
        $anchorScroll();
      };

      $scope.firmwares = [];
      $scope.bmcActiveVersion = '';
      $scope.hostActiveVersion = '';
      $scope.display_error = false;
      $scope.activate_confirm = false;
      $scope.delete_image_id = '';
      $scope.delete_image_version = '';
      $scope.activate_image_id = '';
      $scope.activate_image_version = '';
      $scope.activate_image_type = '';
      $scope.priority_image_id = '';
      $scope.priority_image_version = '';
      $scope.priority_from = -1;
      $scope.priority_to = -1;
      $scope.confirm_priority = false;
      $scope.file_empty = true;
      $scope.uploading = false;
      $scope.upload_success = false;
      $scope.activate = {reboot: true};
      $scope.download_error_msg = '';
      $scope.download_success = false;

      var pollActivationTimer = undefined;
      var pollDownloadTimer = undefined;

      $scope.error = {modal_title: '', title: '', desc: '', type: 'warning'};

      $scope.activateImage = function(imageId, imageVersion, imageType) {
        $scope.activate_image_id = imageId;
        $scope.activate_image_version = imageVersion;
        $scope.activate_image_type = imageType;
        $scope.activate_confirm = true;
      };

      $scope.displayError = function(data) {
        $scope.error = data;
        $scope.display_error = true;
      };

      function waitForActive(imageId) {
        var deferred = $q.defer();
        var startTime = new Date();
        pollActivationTimer = $interval(function() {
          APIUtils.getActivation(imageId).then(
              function(state) {
                //@TODO: display an error message if image "Failed"
                if (((/\.Active$/).test(state.data)) ||
                    ((/\.Failed$/).test(state.data))) {
                  $interval.cancel(pollActivationTimer);
                  pollActivationTimer = undefined;
                  deferred.resolve(state);
                }
              },
              function(error) {
                $interval.cancel(pollActivationTimer);
                pollActivationTimer = undefined;
                console.log(error);
                deferred.reject(error);
              });
          var now = new Date();
          if ((now.getTime() - startTime.getTime()) >=
              Constants.TIMEOUT.ACTIVATION) {
            $interval.cancel(pollActivationTimer);
            pollActivationTimer = undefined;
            console.log('Time out activating image, ' + imageId);
            deferred.reject(
                'Time out. Image did not activate in allotted time.');
          }
        }, Constants.POLL_INTERVALS.ACTIVATION);
        return deferred.promise;
      }

      $scope.activateConfirmed = function() {
        APIUtils.activateImage($scope.activate_image_id)
            .then(
                function(state) {
                  $scope.loadFirmwares();
                  return state;
                },
                function(error) {
                  $scope.displayError({
                    modal_title: 'Error during activation call',
                    title: 'Error during activation call',
                    desc: JSON.stringify(error.data),
                    type: 'Error'
                  });
                })
            .then(function(activationState) {
              waitForActive($scope.activate_image_id)
                  .then(
                      function(state) {
                        $scope.loadFirmwares();
                      },
                      function(error) {
                        $scope.displayError({
                          modal_title: 'Error during image activation',
                          title: 'Error during image activation',
                          desc: JSON.stringify(error.data),
                          type: 'Error'
                        });
                      })
                  .then(function(state) {
                    if ($scope.activate.reboot &&
                        ($scope.activate_image_type == 'BMC')) {
                      // Despite the new image being active, issue,
                      // https://github.com/openbmc/openbmc/issues/2764, can
                      // cause a system to brick, if the system reboots before
                      // the service to set the U-Boot variables is complete.
                      // Wait 10 seconds before rebooting to ensure this service
                      // is complete. This issue is fixed in newer images, but
                      // the user may be updating from an older image that does
                      // not that have this fix.
                      // TODO: remove this timeout after sufficient time has
                      // passed.
                      $timeout(function() {
                        APIUtils.bmcReboot(
                            function(response) {},
                            function(error) {
                              $scope.displayError({
                                modal_title: 'Error during BMC reboot',
                                title: 'Error during BMC reboot',
                                desc: JSON.stringify(error.data),
                                type: 'Error'
                              });
                            });
                      }, 10000);
                    }
                    if ($scope.activate.reboot &&
                        ($scope.activate_image_type == 'Host')) {
                      // If image type being activated is a host image, the
                      // current power status of the server determines if the
                      // server should power on or reboot.
                      if ($scope.isServerOff()) {
                        powerOn();
                      } else {
                        warmReboot();
                      }
                    }
                  });
            });
        $scope.activate_confirm = false;
      };
      function powerOn() {
        dataService.setUnreachableState();
        APIUtils.hostPowerOn()
            .then(function(response) {
              return response;
            })
            .then(function(lastStatus) {
              return APIUtils.pollHostStatusTillOn();
            })
            .catch(function(error) {
              dataService.activateErrorModal({
                title: Constants.MESSAGES.POWER_OP.POWER_ON_FAILED,
                description: error.statusText ?
                    $interpolate(
                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
                        {status: error.status, description: error.statusText}) :
                    error
              });
            });
      };
      function warmReboot() {
        $scope.uploading = true;
        dataService.setUnreachableState();
        APIUtils.hostReboot()
            .then(function(response) {
              return response;
            })
            .then(function(lastStatus) {
              return APIUtils.pollHostStatusTilReboot();
            })
            .catch(function(error) {
              dataService.activateErrorModal({
                title: Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED,
                description: error.statusText ?
                    $interpolate(
                        Constants.MESSAGES.ERROR_MESSAGE_DESC_TEMPLATE)(
                        {status: error.status, description: error.statusText}) :
                    error
              });
            });
      };
      $scope.isServerOff = function() {
        return dataService.server_state === Constants.HOST_STATE_TEXT.off;
      };

      $scope.upload = function() {
        if ($scope.file) {
          $scope.uploading = true;
          $scope.upload_success = false;
          APIUtils.uploadImage($scope.file)
              .then(
                  function(response) {
                    $scope.file = '';
                    $scope.uploading = false;
                    $scope.upload_success = true;
                    $scope.loadFirmwares();
                  },
                  function(error) {
                    $scope.uploading = false;
                    console.log(error);
                    $scope.displayError({
                      modal_title: 'Error during image upload',
                      title: 'Error during image upload',
                      desc: error,
                      type: 'Error'
                    });
                  });
        }
      };

      // TODO: openbmc/openbmc#1691 Add support to return
      // the id of the newly created image, downloaded via
      // tftp. Polling the number of software objects is a
      // near term solution.
      function waitForDownload() {
        var deferred = $q.defer();
        var startTime = new Date();
        pollDownloadTimer = $interval(function() {
          var now = new Date();
          if ((now.getTime() - startTime.getTime()) >=
              Constants.TIMEOUT.DOWNLOAD_IMAGE) {
            $interval.cancel(pollDownloadTimer);
            pollDownloadTimer = undefined;
            deferred.reject(
                new Error(Constants.MESSAGES.POLL.DOWNLOAD_IMAGE_TIMEOUT));
          }

          APIUtils.getFirmwares().then(
              function(response) {
                if (response.data.length === $scope.firmwares.length + 1) {
                  $interval.cancel(pollDownloadTimer);
                  pollDownloadTimer = undefined;
                  deferred.resolve(response.data);
                }
              },
              function(error) {
                $interval.cancel(pollDownloadTimer);
                pollDownloadTimer = undefined;
                deferred.reject(error);
              });
        }, Constants.POLL_INTERVALS.DOWNLOAD_IMAGE);

        return deferred.promise;
      }

      $scope.download = function() {
        $scope.download_success = false;
        $scope.download_error_msg = '';
        if (!$scope.download_host || !$scope.download_filename) {
          $scope.download_error_msg = 'Field is required!';
          return false;
        }

        $scope.downloading = true;
        APIUtils.getFirmwares()
            .then(function(response) {
              $scope.firmwares = response.data;
            })
            .then(function() {
              return APIUtils
                  .downloadImage($scope.download_host, $scope.download_filename)
                  .then(function(downloadStatus) {
                    return downloadStatus;
                  });
            })
            .then(function(downloadStatus) {
              return waitForDownload();
            })
            .then(
                function(newFirmwareList) {
                  $scope.download_host = '';
                  $scope.download_filename = '';
                  $scope.downloading = false;
                  $scope.download_success = true;
                  $scope.loadFirmwares();
                },
                function(error) {
                  console.log(error);
                  $scope.displayError({
                    modal_title: 'Error during downloading Image',
                    title: 'Error during downloading Image',
                    desc: error,
                    type: 'Error'
                  });
                  $scope.downloading = false;
                });
      };

      $scope.changePriority = function(imageId, imageVersion, from, to) {
        $scope.priority_image_id = imageId;
        $scope.priority_image_version = imageVersion;
        $scope.priority_from = from;
        $scope.priority_to = to;
        $scope.confirm_priority = true;
      };

      $scope.confirmChangePriority = function() {
        $scope.loading = true;
        APIUtils.changePriority($scope.priority_image_id, $scope.priority_to)
            .then(function(response) {
              $scope.loading = false;
              if (response.status == 'error') {
                $scope.displayError({
                  modal_title: response.data.description,
                  title: response.data.description,
                  desc: response.data.exception,
                  type: 'Error'
                });
              } else {
                $scope.loadFirmwares();
              }
            });
        $scope.confirm_priority = false;
      };
      $scope.deleteImage = function(imageId, imageVersion) {
        $scope.delete_image_id = imageId;
        $scope.delete_image_version = imageVersion;
        $scope.confirm_delete = true;
      };
      $scope.confirmDeleteImage = function() {
        $scope.loading = true;
        APIUtils.deleteImage($scope.delete_image_id).then(function(response) {
          $scope.loading = false;
          if (response.status == 'error') {
            $scope.displayError({
              modal_title: response.data.description,
              title: response.data.description,
              desc: response.data.exception,
              type: 'Error'
            });
          } else {
            $scope.loadFirmwares();
          }
        });
        $scope.confirm_delete = false;
      };
      $scope.fileNameChanged = function() {
        $scope.file_empty = false;
      };

      $scope.filters = {bmc: {imageType: 'BMC'}, host: {imageType: 'Host'}};

      $scope.loadFirmwares = function() {
        APIUtils.getFirmwares().then(function(result) {
          $scope.firmwares = result.data;
          $scope.bmcActiveVersion = result.bmcActiveVersion;
          $scope.hostActiveVersion = result.hostActiveVersion;
        });
      };

      $scope.loadFirmwares();
    }
  ]);
})(angular);
