/**
 * 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',
    function(
        $scope, $window, APIUtils, dataService, $location, $anchorScroll,
        Constants, $interval, $q, $timeout) {
      $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) {
                    // Only look at reboot if it's a BMC image
                    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);
                    }
                  });
            });
        $scope.activate_confirm = false;
      };

      $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);
