# Copyright 2011 Quanta Research Cambridge, Inc.
#
#    Licensed 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.
"""Defines various sub-classes of the `StressTestCase` and
`PendingAction` class. The sub-classes of StressTestCase implement various
API calls on the Nova cluster having to do with Server Actions. Each
sub-class will have a corresponding PendingAction. These pending
actions veriy that the API call was successful or not."""


# system imports
import random
import time

# local imports
import test_case
import pending_action
from tempest.exceptions import TimeoutException
from utils.util import *


class TestRebootVM(test_case.StressTestCase):
    """Reboot a server"""

    def run(self, manager, state, *pargs, **kwargs):
        """
        Send an HTTP POST request to the nova cluster to reboot a random
        server. Update state of object in `state` variable to indicate that
        it is rebooting.
        `manager` : Manager object
        `state`      : `State` object describing our view of state of cluster
        `pargs`      : positional arguments
        `kwargs`     : keyword arguments, which include:
                       `timeout` : how long to wait before issuing Exception
                       `type`    : reboot type [SOFT or HARD] (default is SOFT)
        """

        vms = state.get_instances()
        active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE']
        # no active vms, so return null
        if not active_vms:
            self._logger.info('no ACTIVE instances to reboot')
            return

        _reboot_type = kwargs.get('type', 'SOFT')

        # select active vm to reboot and then send request to nova controller
        target = random.choice(active_vms)
        reboot_target = target[0]

        response, body = manager.servers_client.reboot(
                                                          reboot_target['id'],
                                                          _reboot_type)
        if (response.status != 202):
            self._logger.error("response: %s" % response)
            raise Exception

        if _reboot_type == 'SOFT':
            state_name = 'REBOOT'
        else:
            state_name = 'REBOOT'  # this is a bug, should be HARD_REBOOT

        self._logger.info('waiting for machine %s to change to %s' %
                          (reboot_target['id'], state_name))

        # check for state transition
        _resp, body = manager.servers_client.get_server(reboot_target['id'])
        if body['status'] == state_name:
            state_string = state_name
        else:
            # grab the actual state as we think it is
            temp_obj = state.get_instances()[self._target['id']]
            self._logger.debug(
                "machine %s in state %s" %
                (reboot_target['id'], temp_obj[1])
                )
            state_string = temp_obj[1]

        if state_string == state_name:
            self._logger.info('machine %s ACTIVE -> %s' %
                              (reboot_target['id'], state_name))
            state.set_instance_state(reboot_target['id'],
                                    (reboot_target, state_name))

        return VerifyRebootVM(manager,
                              state,
                              reboot_target,
                              reboot_type=_reboot_type,
                              state_name=state_string)


class VerifyRebootVM(pending_action.PendingAction):
    """Class to verify that the reboot completed."""
    States = enum('REBOOT_CHECK', 'ACTIVE_CHECK')

    def __init__(self, manager, state, target_server,
                 reboot_type=None,
                 state_name=None,
                 ip_addr=None):
        super(VerifyRebootVM, self).__init__(manager,
                                             state,
                                             target_server)
        # FIX ME: this is a nova bug
        if reboot_type == 'SOFT':
            self._reboot_state = 'REBOOT'
        else:
            self._reboot_state = 'REBOOT'  # should be HARD REBOOT

        if state_name == 'ACTIVE':  # was still active, check to see if REBOOT
            self._retry_state = self.States.REBOOT_CHECK
        else:  # was REBOOT, so now check for ACTIVE
            self._retry_state = self.States.ACTIVE_CHECK

    def retry(self):
        """
        Check to see that the server of interest has actually rebooted. Update
        state to indicate that server is running again.
        """
        # don't run reboot verification if target machine has been
        # deleted or is going to be deleted
        if (self._target['id'] not in self._state.get_instances().keys() or
            self._state.get_instances()[self._target['id']][1] ==
            'TERMINATING'):
            self._logger.debug('machine %s is deleted or TERMINATING' %
                               self._target['id'])
            return True

        if time.time() - self._start_time > self._timeout:
            raise TimeoutException
        reboot_state = self._reboot_state
        if self._retry_state == self.States.REBOOT_CHECK:
            server_state = self._check_for_status(reboot_state)
            if server_state == reboot_state:
                self._logger.info('machine %s ACTIVE -> %s' %
                                  (self._target['id'], reboot_state))
                self._state.set_instance_state(self._target['id'],
                                              (self._target, reboot_state)
                                              )
                self._retry_state = self.States.ACTIVE_CHECK
            elif server_state == 'ACTIVE':
                # machine must have gone ACTIVE -> REBOOT ->ACTIVE
                self._retry_state = self.States.ACTIVE_CHECK

        elif self._retry_state == self.States.ACTIVE_CHECK:
            if not self._check_for_status('ACTIVE'):
                return False
        target = self._target
        self._logger.info('machine %s REBOOT -> ACTIVE [%.1f secs elapsed]' %
                              (target['id'], time.time() - self._start_time))
        self._state.set_instance_state(target['id'],
                                      (target, 'ACTIVE'))

        return True

# This code needs to be tested against a cluster that supports resize.
#class TestResizeVM(test_case.StressTestCase):
#    """Resize a server (change flavors)"""
#
#    def run(self, manager, state, *pargs, **kwargs):
#        """
#        Send an HTTP POST request to the nova cluster to resize a random
#        server. Update `state` to indicate server is rebooting.
#
#        `manager` : Manager object.
#        `state`      : `State` object describing our view of state of cluster
#        `pargs`      : positional arguments
#        `kwargs`     : keyword arguments, which include:
#                       `timeout` : how long to wait before issuing Exception
#        """
#
#        vms = state.get_instances()
#        active_vms = [v for k, v in vms.iteritems() if v and v[1] == 'ACTIVE']
#        # no active vms, so return null
#        if not active_vms:
#            self._logger.debug('no ACTIVE instances to resize')
#            return
#
#        target = random.choice(active_vms)
#        resize_target = target[0]
#        print resize_target
#
#        _timeout = kwargs.get('timeout', 600)
#
#        # determine current flavor type, and resize to a different type
#        # m1.tiny -> m1.small, m1.small -> m1.tiny
#        curr_size = int(resize_target['flavor']['id'])
#        if curr_size == 1:
#            new_size = 2
#        else:
#            new_size = 1
#        flavor_type = { 'flavorRef': new_size } # resize to m1.small
#
#        post_body = json.dumps({'resize' : flavor_type})
#        url = '/servers/%s/action' % resize_target['id']
#        (response, body) = manager.request('POST',
#                                              url,
#                                              body=post_body)
#
#        if (response.status != 202):
#            self._logger.error("response: %s" % response)
#            raise Exception
#
#        state_name = check_for_status(manager, resize_target, 'RESIZE')
#
#        if state_name == 'RESIZE':
#            self._logger.info('machine %s: ACTIVE -> RESIZE' %
#                              resize_target['id'])
#            state.set_instance_state(resize_target['id'],
#                                    (resize_target, 'RESIZE'))
#
#        return VerifyResizeVM(manager,
#                              state,
#                              resize_target,
#                              state_name=state_name,
#                              timeout=_timeout)
#
#class VerifyResizeVM(pending_action.PendingAction):
#    """Verify that resizing of a VM was successful"""
#    States = enum('VERIFY_RESIZE_CHECK', 'ACTIVE_CHECK')
#
#    def __init__(self, manager, state, created_server,
#                 state_name=None,
#                 timeout=300):
#        super(VerifyResizeVM, self).__init__(manager,
#                                             state,
#                                             created_server,
#                                             timeout=timeout)
#        self._retry_state = self.States.VERIFY_RESIZE_CHECK
#        self._state_name = state_name
#
#    def retry(self):
#        """
#        Check to see that the server was actually resized. And change `state`
#        of server to running again.
#        """
#        # don't run resize if target machine has been deleted
#        # or is going to be deleted
#        if (self._target['id'] not in self._state.get_instances().keys() or
#            self._state.get_instances()[self._target['id']][1] ==
#           'TERMINATING'):
#            self._logger.debug('machine %s is deleted or TERMINATING' %
#                               self._target['id'])
#            return True
#
#        if time.time() - self._start_time > self._timeout:
#            raise TimeoutException
#
#        if self._retry_state == self.States.VERIFY_RESIZE_CHECK:
#            if self._check_for_status('VERIFY_RESIZE') == 'VERIFY_RESIZE':
#                # now issue command to CONFIRM RESIZE
#                post_body = json.dumps({'confirmResize' : null})
#                url = '/servers/%s/action' % self._target['id']
#                (response, body) = manager.request('POST',
#                                                      url,
#                                                      body=post_body)
#                if (response.status != 204):
#                    self._logger.error("response: %s" % response)
#                    raise Exception
#
#                self._logger.info(
#                    'CONFIRMING RESIZE of machine %s [%.1f secs elapsed]' %
#                    (self._target['id'], time.time() - self._start_time)
#                    )
#                state.set_instance_state(self._target['id'],
#                                        (self._target, 'CONFIRM_RESIZE'))
#
#                # change states
#                self._retry_state = self.States.ACTIVE_CHECK
#
#            return False
#
#        elif self._retry_state == self.States.ACTIVE_CHECK:
#            if not self._check_manager("ACTIVE"):
#                return False
#            else:
#                server = self._manager.get_server(self._target['id'])
#
#                # Find private IP of server?
#                try:
#                    (_, network) = server['addresses'].popitem()
#                    ip = network[0]['addr']
#                except KeyError:
#                    self._logger.error(
#                        'could not get ip address for machine %s' %
#                        self._target['id']
#                        )
#                    raise Exception
#
#                self._logger.info(
#                    'machine %s: VERIFY_RESIZE -> ACTIVE [%.1f sec elapsed]' %
#                    (self._target['id'], time.time() - self._start_time)
#                    )
#                self._state.set_instance_state(self._target['id'],
#                                              (self._target, 'ACTIVE'))
#
#                return True
#
#        else:
#            # should never get here
#            self._logger.error('Unexpected state')
#            raise Exception
