# Copyright 2012 OpenStack Foundation
# All Rights Reserved.
#
#    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.
import time

import pytest
import allure

from tests.api.volume import base
from common import waiters
from configs import config
from lib import exceptions

CONF = config.CONF


class TestVolumesActions(base.BaseVolumeTest):
    """Test volume actions"""

    create_default_network = True

    @classmethod
    def resource_setup(cls):
        super(TestVolumesActions, cls).resource_setup()

        # Create a test shared volume for attach/detach tests
        if (
            not CONF.common.availability_zone_list
            or len(CONF.common.availability_zone_list) < 1
        ):
            raise cls.skipException(
                "can't resource setup, there is no availability_zone_list"
            )
        cls.volume = cls.create_volume(
            availability_zone=CONF.common.availability_zone_list[0]
        )

    @pytest.mark.smoke
    @pytest.mark.positive
    @pytest.mark.skipif(
        not CONF.common.availability_zone_list
        or len(CONF.common.availability_zone_list) < 1,
        reason="There is no availability_zone_list for test.",
    )
    def test_attach_detach_volume_to_instance(self):
        """Test attaching and detaching volume to instance

        :ref: `test_attach_detach_volume_to_instance <https://docs.openstack.org/tempest/latest/tests/volume/volume.html#volume.test_volumes_actions.VolumesActionsTest.test_attach_detach_volume_to_instance>`__
        """
        # Create a server
        with allure.step("Create a server"):
            server = self.create_server(
                availability_zone=CONF.common.availability_zone_list[0]
            )
            assert server["id"], "Failed to create server for test"
        # Volume is attached and detached successfully from an instance
        time.sleep(10)
        with allure.step("Validate Attached volume to instance"):
            resp = self.servers_client.attach_volume(
                server["id"], volumeId=self.volume["id"]
            )
            assert (
                resp.response["status"] == "200"
            ), "Failed to attached volume to instance"
        with allure.step("Wait Volume status to 'in-use' after volume attach"):
            try:
                waiters.wait_for_volume_resource_status(
                    self.volumes_client, self.volume["id"], "in-use"
                )
            except exceptions.TimeoutException:
                assert (
                    False
                ), "Failed to wait volume status to 'in-use' after volume attach"

        # Wait reason: There is a problem if run Detach immediately after status 'in-use' changed.
        time.sleep(5)

        with allure.step("Validate Detached volume to instance"):
            resp = self.servers_client.detach_volume(
                server["id"], volume_id=self.volume["id"]
            )
            assert (
                resp.response["status"] == "202"
            ), "Failed to detached volume to instance"
        with allure.step("Wait Volume status to 'available' after volume detach"):
            try:
                waiters.wait_for_volume_resource_status(
                    self.volumes_client, self.volume["id"], "available"
                )
            except exceptions.TimeoutException:
                assert (
                    False
                ), "Failed to wait volume status to 'available' after volume detach"