Add fixes for cold reboot

This fixes the cold reboot issue with the following steps

- It applies the command to shut off the chassis.
- Then verify the chassis is off. It checks for every 5 seconds.
  During this time the spinner displays. A 5min timeout has been
  added.
- Once the chassis is off, it turns on the host.

fixes openbmc/openbmc#2795

Change-Id: I119a1c95e57c10ccee27be1512a1fc38cde307fa
Signed-off-by: Iftekharul Islam <iffy.ryan@ibm.com>
Signed-off-by: CamVan Nguyen <ctnguyen@us.ibm.com>
diff --git a/app/server-control/controllers/power-operations-controller.js b/app/server-control/controllers/power-operations-controller.js
index 4ae753e..461c1e7 100644
--- a/app/server-control/controllers/power-operations-controller.js
+++ b/app/server-control/controllers/power-operations-controller.js
@@ -16,8 +16,11 @@
             '$scope',
             'APIUtils',
             'dataService',
+            'Constants',
             '$timeout',
-            function($scope, APIUtils, dataService, $timeout){
+            '$interval',
+            '$q',
+            function($scope, APIUtils, dataService, Constants, $timeout, $interval, $q){
                 $scope.dataService = dataService;
                 $scope.confirm = false;
                 $scope.power_confirm = false;
@@ -25,6 +28,11 @@
                 $scope.coldboot_confirm = false;
                 $scope.orderly_confirm = false;
                 $scope.immediately_confirm = false;
+                $scope.loading = false;
+
+                var pollChassisStatusTimer = undefined;
+                var pollHostStatusTimer = undefined;
+                var pollStartTime = null;
 
                 //@TODO: call api and get proper state
                 $scope.toggleState = function(){
@@ -33,8 +41,8 @@
 
                 $scope.togglePower = function(){
                     var method = (dataService.server_state == 'Running') ? 'hostPowerOff' : 'hostPowerOn';
-                     //@TODO: show progress or set class orange
-                    APIUtils[method](function(response){
+                    //@TODO: show progress or set class orange
+                    APIUtils[method]().then(function(response){
                         //update state based on response
                         //error case?
                         if(response == null){
@@ -56,10 +64,59 @@
                     $scope.confirm = true;
                     $scope.power_confirm = true;
                 };
+
+                function pollChassisStatusTillOff(){
+                    var deferred = $q.defer();
+                    pollChassisStatusTimer = $interval(function(){
+                        var now = new Date();
+                        if((now.getTime() - pollStartTime.getTime()) >= Constants.TIMEOUT.CHASSIS_OFF){
+                            $interval.cancel(pollChassisStatusTimer);
+                            pollChassisStatusTimer = undefined;
+                            deferred.reject(new Error(Constants.MESSAGES.POLL.TIMEOUT));
+                        }
+                        APIUtils.getChassisState().then(function(state){
+                            if(state === Constants.CHASSIS_POWER_STATE.off_code){
+                                $interval.cancel(pollChassisStatusTimer);
+                                pollChassisStatusTimer = undefined;
+                                deferred.resolve(state);
+                            }
+                        }).catch(function(error){
+                            $interval.cancel(pollChassisStatusTimer);
+                            pollChassisStatusTimer = undefined;
+                            deferred.reject(error);
+                        });
+                    }, Constants.POLL_INTERVALS.POWER_OP);
+
+                    return deferred.promise;
+                }
+                function pollHostStatusTillOn(){
+                    var deferred = $q.defer();
+                    pollHostStatusTimer = $interval(function(){
+                        var now = new Date();
+                        if((now.getTime() - pollStartTime.getTime()) >= Constants.TIMEOUT.HOST_ON){
+                            $interval.cancel(pollHostStatusTimer);
+                            pollHostStatusTimer = undefined;
+                            deferred.reject(new Error(Constants.MESSAGES.POLL.TIMEOUT));
+                        }
+                        APIUtils.getHostState().then(function(state){
+                            if(state === Constants.HOST_STATE_TEXT.on_code){
+                                $interval.cancel(pollHostStatusTimer);
+                                pollHostStatusTimer = undefined;
+                                deferred.resolve(state);
+                            }
+                        }).catch(function(error){
+                            $interval.cancel(pollHostStatusTimer);
+                            pollHostStatusTimer = undefined;
+                            deferred.reject(error);
+                        });
+                    }, Constants.POLL_INTERVALS.POWER_OP);
+
+                    return deferred.promise;
+                }
                 $scope.warmReboot = function(){
                     //@TODO:show progress
                     dataService.setBootingState();
-                    APIUtils.hostReboot(function(response){
+                    APIUtils.hostReboot().then(function(response){
                         if(response){
                             dataService.setPowerOnState();
                         }else{
@@ -84,7 +141,26 @@
                 };
 
                 $scope.coldReboot = function(){
-                    $scope.warmReboot();
+                    $scope.loading = true;
+                    dataService.setBootingState();
+                    APIUtils.chassisPowerOff().then(function(state){
+                        return state;
+                    }).then(function(lastState) {
+                        pollStartTime = new Date();
+                        return pollChassisStatusTillOff();
+                    }).then(function(chassisState) {
+                        APIUtils.hostPowerOn().then(function(hostState){
+                            return hostState;
+                        })
+                    }).then(function(hostState) {
+                        pollStartTime = new Date();
+                        return pollHostStatusTillOn();
+                    }).then(function(state) {
+                        dataService.setPowerOnState();
+                        $scope.loading = false;
+                    }).catch(function(error){
+                        $scope.loading = false;
+                    });
                 };
                 $scope.coldRebootConfirm = function(){
                     if($scope.confirm) {
@@ -96,7 +172,7 @@
 
                 $scope.orderlyShutdown = function(){
                     //@TODO:show progress
-                    APIUtils.hostPowerOff(function(response){
+                    APIUtils.hostPowerOff().then(function(response){
                         if(response){
                             dataService.setPowerOffState();
                         }else{