#    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 logging
import six
from testtools import testcase

from cinderclient import exceptions as cinder_exceptions

from heat_integrationtests.common import exceptions
from heat_integrationtests.common import test

LOG = logging.getLogger(__name__)


class VolumeBackupRestoreIntegrationTest(test.HeatIntegrationTest):

    def setUp(self):
        super(VolumeBackupRestoreIntegrationTest, self).setUp()
        self.client = self.orchestration_client
        if self.conf.keypair_name:
            self.keypair_name = self.conf.keypair_name
        else:
            self.keypair = self.create_keypair()
            self.keypair_name = self.keypair.id
        self.volume_description = 'A test volume description 123'
        self.volume_size = self.conf.volume_size

    def _cinder_verify(self, volume_id, expected_status='available'):
        self.assertIsNotNone(volume_id)
        volume = self.volume_client.volumes.get(volume_id)
        self.assertIsNotNone(volume)
        self.assertEqual(expected_status, volume.status)
        self.assertEqual(self.volume_size, volume.size)
        self.assertEqual(self.volume_description,
                         volume.display_description)

    def _outputs_verify(self, stack, expected_status='available'):
        self.assertEqual(expected_status,
                         self._stack_output(stack, 'status'))
        self.assertEqual(six.text_type(self.volume_size),
                         self._stack_output(stack, 'size'))
        self.assertEqual(self.volume_description,
                         self._stack_output(stack, 'display_description'))

    def _create_stack(self, template_name, add_parameters={}):
        # TODO(shardy): refactor this into a generic base-class helper
        net = self._get_default_network()
        stack_name = self._stack_rand_name()
        template = self._load_template(__file__, template_name)
        parameters = {'key_name': self.keypair_name,
                      'instance_type': self.conf.instance_type,
                      'image_id': self.conf.minimal_image_ref,
                      'volume_description': self.volume_description,
                      'timeout': self.conf.build_timeout,
                      'network': net['id']}
        parameters.update(add_parameters)
        ret_stack = self.client.stacks.create(
            stack_name=stack_name,
            template=template,
            parameters=parameters)
        stack_id = ret_stack['stack']['id']
        stack = self.client.stacks.get(stack_id)
        self.assertIsNotNone(stack)
        stack_identifier = '%s/%s' % (stack_name, stack.id)

        self.addCleanup(self._stack_delete, stack_identifier)
        self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
        return stack, stack_identifier

    @testcase.skip('Skipped until failure rate '
                   'can be reduced ref bug #1382300')
    def test_cinder_volume_create_backup_restore(self):
        """Ensure the 'Snapshot' deletion policy works.

           This requires a more complex test, but it tests several aspects
           of the heat cinder resources:
           1. Create a volume, attach it to an instance, write some data to it
           2. Delete the stack, with 'Snapshot' specified, creates a backup
           3. Check the snapshot has created a volume backup
           4. Create a new stack, where the volume is created from the backup
           5. Verify the test data written in (1) is present in the new volume
        """
        stack, stack_identifier = self._create_stack(
            template_name='test_volumes_delete_snapshot.yaml',
            add_parameters={'volume_size': self.volume_size})

        # Verify with cinder that the volume exists, with matching details
        volume_id = self._stack_output(stack, 'volume_id')
        self._cinder_verify(volume_id, expected_status='in-use')

        # Verify the stack outputs are as expected
        self._outputs_verify(stack, expected_status='in-use')

        # Delete the stack and ensure a backup is created for volume_id
        # but the volume itself is gone
        self.client.stacks.delete(stack_identifier)
        self._wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE')
        self.assertRaises(cinder_exceptions.NotFound,
                          self.volume_client.volumes.get,
                          volume_id)

        backups = self.volume_client.backups.list()
        self.assertIsNotNone(backups)
        backups_filtered = [b for b in backups if b.volume_id == volume_id]
        self.assertEqual(1, len(backups_filtered))
        backup = backups_filtered[0]
        self.addCleanup(self.volume_client.backups.delete, backup.id)

        # Now, we create another stack where the volume is created from the
        # backup created by the previous stack
        try:
            stack2, stack_identifier2 = self._create_stack(
                template_name='test_volumes_create_from_backup.yaml',
                add_parameters={'backup_id': backup.id})
        except exceptions.StackBuildErrorException as e:
            LOG.error("Halting test due to bug: #1382300")
            LOG.exception(e)
            return

        # Verify with cinder that the volume exists, with matching details
        volume_id2 = self._stack_output(stack2, 'volume_id')
        self._cinder_verify(volume_id2, expected_status='in-use')

        # Verify the stack outputs are as expected
        self._outputs_verify(stack2, expected_status='in-use')
        testfile_data = self._stack_output(stack2, 'testfile_data')
        self.assertEqual('{"instance1": "Volume Data:ateststring"}',
                         testfile_data)

        # Delete the stack and ensure the volume is gone
        self.client.stacks.delete(stack_identifier2)
        self._wait_for_stack_status(stack_identifier2, 'DELETE_COMPLETE')
        self.assertRaises(cinder_exceptions.NotFound,
                          self.volume_client.volumes.get,
                          volume_id2)
