# 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 creating and deleting VMs.
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


class TestCreateVM(test_case.StressTestCase):
    """Create a virtual machine in the Nova cluster."""
    _vm_id = 0

    def run(self, manager, state, *pargs, **kwargs):
        """
        Send an HTTP POST request to the nova cluster to build a
        server. Update the state variable to track state of new server
        and set to PENDING state.

        `manager` : Manager object.
        `state`      : `State` object describing our view of state of cluster
        `pargs`      : positional arguments
        `kwargs`     : keyword arguments, which include:
                       `key_name`  : name of keypair
                       `timeout`   : how long to wait before issuing Exception
                       `image_ref` : index to image types availablexs
                       `flavor_ref`: index to flavor types available
                                     (default = 1, which is tiny)
        """

        # restrict number of instances we can launch
        if len(state.get_instances()) >= state.get_max_instances():
            self._logger.debug("maximum number of instances created: %d" %
                               state.get_max_instances())
            return None

        _key_name = kwargs.get('key_name', '')
        _timeout = int(kwargs.get('timeout',
                                  manager.config.compute.build_timeout))
        _image_ref = kwargs.get('image_ref', manager.config.compute.image_ref)
        _flavor_ref = kwargs.get('flavor_ref',
                                 manager.config.compute.flavor_ref)

        expected_server = {
            'name': 'server' + str(TestCreateVM._vm_id),
            'metadata': {
                'key1': 'value1',
                'key2': 'value2',
                },
            'imageRef': _image_ref,
            'flavorRef': _flavor_ref,
            'adminPass': 'testpwd',
            'key_name': _key_name
            }
        TestCreateVM._vm_id = TestCreateVM._vm_id + 1
        response, body = manager.servers_client.create_server(
                                         expected_server['name'],
                                         _image_ref,
                                         _flavor_ref,
                                         meta=expected_server['metadata'],
                                         adminPass=expected_server['adminPass']
                                         )

        if (response.status != 202):
            self._logger.error("response: %s" % response)
            self._logger.error("body: %s" % body)
            raise Exception

        created_server = body

        self._logger.info('setting machine %s to BUILD' %
                          created_server['id'])
        state.set_instance_state(created_server['id'],
                                (created_server, 'BUILD'))

        return VerifyCreateVM(manager,
                              state,
                              created_server,
                              expected_server)


class VerifyCreateVM(pending_action.PendingAction):
    """Verify that VM was built and is running"""
    def __init__(self, manager,
                 state,
                 created_server,
                 expected_server):
        super(VerifyCreateVM, self).__init__(manager,
                                             state,
                                             created_server,
                                             )
        self._expected = expected_server

    def retry(self):
        """
        Check to see that the server was created and is running.
        Update local view of state to indicate that it is running.
        """
        # don't run create 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.info('machine %s is deleted or TERMINATING' %
                               self._target['id'])
            return True

        time_diff = time.time() - self._start_time
        if time_diff > self._timeout:
            self._logger.error('%d exceeded launch server timeout of %d' %
                               (time_diff, self._timeout))
            raise TimeoutException

        admin_pass = self._target['adminPass']
        # Could check more things here.
        if (self._expected['adminPass'] != admin_pass):
            self._logger.error('expected: %s' %
                               (self._expected['adminPass']))
            self._logger.error('returned: %s' %
                               (admin_pass))
            raise Exception

        if self._check_for_status('ACTIVE') != 'ACTIVE':
            return False

        self._logger.info('machine %s: BUILD -> ACTIVE [%.1f secs elapsed]' %
                          (self._target['id'], time.time() - self._start_time))
        self._state.set_instance_state(self._target['id'],
                                      (self._target, 'ACTIVE'))
        return True


class TestKillActiveVM(test_case.StressTestCase):
    """Class to destroy a random ACTIVE server."""
    def run(self, manager, state, *pargs, **kwargs):
        """
        Send an HTTP POST request to the nova cluster to destroy
        a random ACTIVE server. Update `state` to indicate TERMINATING.

        `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
        """
        # check for active instances
        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 delete')
            return

        _timeout = kwargs.get('timeout', manager.config.compute.build_timeout)

        target = random.choice(active_vms)
        killtarget = target[0]
        manager.servers_client.delete_server(killtarget['id'])
        self._logger.info('machine %s: ACTIVE -> TERMINATING' %
                          killtarget['id'])
        state.set_instance_state(killtarget['id'],
                                (killtarget, 'TERMINATING'))
        return VerifyKillActiveVM(manager, state,
                                  killtarget, timeout=_timeout)


class VerifyKillActiveVM(pending_action.PendingAction):
    """Verify that server was destroyed"""

    def retry(self):
        """
        Check to see that the server of interest is destroyed. Update
        state to indicate that server is destroyed by deleting it from local
        view of state.
        """
        tid = self._target['id']
        # if target machine has been deleted from the state, then it was
        # already verified to be deleted
        if (not tid in self._state.get_instances().keys()):
            return False

        time_diff = time.time() - self._start_time
        if time_diff > self._timeout:
            self._logger.error('server %s: %d exceeds terminate timeout %d' %
                               (tid, time_diff, self._timeout))
            raise TimeoutException

        try:
            self._manager.servers_client.get_server(tid)
        except Exception:
            # if we get a 404 response, is the machine really gone?
            target = self._target
            self._logger.info('machine %s: DELETED [%.1f secs elapsed]' %
                              (target['id'], time.time() - self._start_time))
            self._state.delete_machine_state(target['id'])
            return True

        return False


class TestKillAnyVM(test_case.StressTestCase):
    """Class to destroy a random server regardless of state."""

    def run(self, manager, state, *pargs, **kwargs):
        """
        Send an HTTP POST request to the nova cluster to destroy
        a random server. Update state to TERMINATING.

        `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()
        # no vms, so return null
        if not vms:
            self._logger.info('no active instances to delete')
            return

        _timeout = kwargs.get('timeout', manager.config.compute.build_timeout)

        target = random.choice(vms)
        killtarget = target[0]

        manager.servers_client.delete_server(killtarget['id'])
        self._state.set_instance_state(killtarget['id'],
                                      (killtarget, 'TERMINATING'))
        # verify object will do the same thing as the active VM
        return VerifyKillAnyVM(manager, state, killtarget, timeout=_timeout)

VerifyKillAnyVM = VerifyKillActiveVM


class TestUpdateVMName(test_case.StressTestCase):
    """Class to change the name of the active server"""
    def run(self, manager, state, *pargs, **kwargs):
        """
        Issue HTTP POST request to change the name of active server.
        Update state of server to reflect name changing.

        `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
        """

        # select one machine from active ones
        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 update')
            return

        _timeout = kwargs.get('timeout', manager.config.compute.build_timeout)

        target = random.choice(active_vms)
        update_target = target[0]

        # Update name by appending '_updated' to the name
        new_name = update_target['name'] + '_updated'
        (response, body) = \
            manager.servers_client.update_server(update_target['id'],
                                                    name=new_name)
        if (response.status != 200):
            self._logger.error("response: %s " % response)
            self._logger.error("body: %s " % body)
            raise Exception

        assert(new_name == body['name'])

        self._logger.info('machine %s: ACTIVE -> UPDATING_NAME' %
                          body['id'])
        state.set_instance_state(body['id'],
                                (body, 'UPDATING_NAME'))

        return VerifyUpdateVMName(manager,
                                  state,
                                  body,
                                  timeout=_timeout)


class VerifyUpdateVMName(pending_action.PendingAction):
    """Check that VM has new name"""
    def retry(self):
        """
        Check that VM has new name. Update local view of `state` to RUNNING.
        """
        # don't run update verification
        # if target machine has been deleted or is going to be deleted
        if (not self._target['id'] in self._state.get_instances().keys() or
            self._state.get_instances()[self._target['id']][1] ==
            'TERMINATING'):
            return False

        if time.time() - self._start_time > self._timeout:
            raise TimeoutException

        response, body = \
            self._manager.serverse_client.get_server(self._target['id'])
        if (response.status != 200):
            self._logger.error("response: %s " % response)
            self._logger.error("body: %s " % body)
            raise Exception

        if self._target['name'] != body['name']:
            self._logger.error(self._target['name'] +
                               ' vs. ' +
                               body['name'])
            raise Exception

        # log the update
        self._logger.info('machine %s: UPDATING_NAME -> ACTIVE' %
                          self._target['id'])
        self._state.set_instance_state(self._target['id'],
                                      (body,
                                       'ACTIVE'))
        return True
