#    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 yaml

from heat_integrationtests.functional import functional_base


LOG = logging.getLogger(__name__)


class HooksTest(functional_base.FunctionalTestsBase):

    def setUp(self):
        super(HooksTest, self).setUp()
        self.template = {'heat_template_version': '2014-10-16',
                         'resources': {
                             'foo_step1': {'type': 'OS::Heat::RandomString'},
                             'foo_step2': {'type': 'OS::Heat::RandomString',
                                           'depends_on': 'foo_step1'},
                             'foo_step3': {'type': 'OS::Heat::RandomString',
                                           'depends_on': 'foo_step2'}}}

    def test_hook_pre_create(self):
        env = {'resource_registry':
               {'resources':
                {'foo_step2':
                 {'hooks': 'pre-create'}}}}
        # Note we don't wait for CREATE_COMPLETE, because we need to
        # signal to clear the hook before create will complete
        stack_identifier = self.stack_create(
            template=self.template,
            environment=env,
            expected_status='CREATE_IN_PROGRESS')
        self._wait_for_resource_status(
            stack_identifier, 'foo_step1', 'CREATE_COMPLETE')
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'INIT_COMPLETE')
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='CREATE paused until Hook pre-create is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
        self.client.resources.signal(stack_identifier, 'foo_step2',
                                     data={'unset_hook': 'pre-create'})
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-create is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
        self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')

    def test_hook_pre_update_nochange(self):
        env = {'resource_registry':
               {'resources':
                {'foo_step2':
                 {'hooks': 'pre-update'}}}}
        stack_identifier = self.stack_create(
            template=self.template,
            environment=env)
        res_before = self.client.resources.get(stack_identifier, 'foo_step2')
        # Note we don't wait for UPDATE_COMPLETE, because we need to
        # signal to clear the hook before update will complete
        self.update_stack(
            stack_identifier,
            template=self.template,
            environment=env,
            expected_status='UPDATE_IN_PROGRESS')

        # Note when a hook is specified, the resource status doesn't change
        # when we hit the hook, so we look for the event, then assert the
        # state is unchanged.
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='UPDATE paused until Hook pre-update is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
        self.client.resources.signal(stack_identifier, 'foo_step2',
                                     data={'unset_hook': 'pre-update'})
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-update is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
        self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
        res_after = self.client.resources.get(stack_identifier, 'foo_step2')
        self.assertEqual(res_before.physical_resource_id,
                         res_after.physical_resource_id)

    def test_hook_pre_update_replace(self):
        env = {'resource_registry':
               {'resources':
                {'foo_step2':
                 {'hooks': 'pre-update'}}}}
        stack_identifier = self.stack_create(
            template=self.template,
            environment=env)
        res_before = self.client.resources.get(stack_identifier, 'foo_step2')
        # Note we don't wait for UPDATE_COMPLETE, because we need to
        # signal to clear the hook before update will complete
        self.template['resources']['foo_step2']['properties'] = {'length': 10}
        self.update_stack(
            stack_identifier,
            template=self.template,
            environment=env,
            expected_status='UPDATE_IN_PROGRESS')

        # Note when a hook is specified, the resource status doesn't change
        # when we hit the hook, so we look for the event, then assert the
        # state is unchanged.
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='UPDATE paused until Hook pre-update is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
        self.client.resources.signal(stack_identifier, 'foo_step2',
                                     data={'unset_hook': 'pre-update'})
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-update is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
        self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
        res_after = self.client.resources.get(stack_identifier, 'foo_step2')
        self.assertNotEqual(res_before.physical_resource_id,
                            res_after.physical_resource_id)

    def test_hook_pre_update_in_place(self):
        env = {'resource_registry':
               {'resources':
                {'rg':
                 {'hooks': 'pre-update'}}}}
        template = {'heat_template_version': '2014-10-16',
                    'resources': {
                        'rg': {
                            'type': 'OS::Heat::ResourceGroup',
                            'properties': {
                                'count': 1,
                                'resource_def': {
                                    'type': 'OS::Heat::RandomString'}}}}}
        # Note we don't wait for CREATE_COMPLETE, because we need to
        # signal to clear the hook before create will complete
        stack_identifier = self.stack_create(
            template=template,
            environment=env)
        res_before = self.client.resources.get(stack_identifier, 'rg')
        template['resources']['rg']['properties']['count'] = 2
        self.update_stack(
            stack_identifier,
            template=template,
            environment=env,
            expected_status='UPDATE_IN_PROGRESS')

        # Note when a hook is specified, the resource status doesn't change
        # when we hit the hook, so we look for the event, then assert the
        # state is unchanged.
        self._wait_for_resource_status(
            stack_identifier, 'rg', 'CREATE_COMPLETE')
        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='UPDATE paused until Hook pre-update is cleared',
            rsrc_name='rg')
        self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
        self.client.resources.signal(stack_identifier, 'rg',
                                     data={'unset_hook': 'pre-update'})

        ev = self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-update is cleared',
            rsrc_name='rg')
        self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
        self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
        res_after = self.client.resources.get(stack_identifier, 'rg')
        self.assertEqual(res_before.physical_resource_id,
                         res_after.physical_resource_id)

    def test_hook_pre_create_nested(self):
        files = {'nested.yaml': yaml.dump(self.template)}
        env = {'resource_registry':
               {'resources':
                {'nested':
                 {'foo_step2':
                  {'hooks': 'pre-create'}}}}}
        template = {'heat_template_version': '2014-10-16',
                    'resources': {
                        'nested': {'type': 'nested.yaml'}}}
        # Note we don't wait for CREATE_COMPLETE, because we need to
        # signal to clear the hook before create will complete
        stack_identifier = self.stack_create(
            template=template,
            environment=env,
            files=files,
            expected_status='CREATE_IN_PROGRESS')
        self._wait_for_resource_status(stack_identifier, 'nested',
                                       'CREATE_IN_PROGRESS')
        nested_identifier = self.assert_resource_is_a_stack(
            stack_identifier, 'nested', wait=True)
        self._wait_for_resource_status(
            nested_identifier, 'foo_step1', 'CREATE_COMPLETE')
        self._wait_for_resource_status(
            nested_identifier, 'foo_step2', 'INIT_COMPLETE')
        ev = self.wait_for_event_with_reason(
            nested_identifier,
            reason='CREATE paused until Hook pre-create is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
        self.client.resources.signal(nested_identifier, 'foo_step2',
                                     data={'unset_hook': 'pre-create'})
        ev = self.wait_for_event_with_reason(
            nested_identifier,
            reason='Hook pre-create is cleared',
            rsrc_name='foo_step2')
        self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
        self._wait_for_resource_status(
            nested_identifier, 'foo_step2', 'CREATE_COMPLETE')
        self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')

    def test_hook_pre_create_wildcard(self):
        env = {'resource_registry':
               {'resources':
                {'foo_*':
                 {'hooks': 'pre-create'}}}}
        # Note we don't wait for CREATE_COMPLETE, because we need to
        # signal to clear the hook before create will complete
        stack_identifier = self.stack_create(
            template=self.template,
            environment=env,
            expected_status='CREATE_IN_PROGRESS')
        self._wait_for_resource_status(
            stack_identifier, 'foo_step1', 'INIT_COMPLETE')
        self.wait_for_event_with_reason(
            stack_identifier,
            reason='CREATE paused until Hook pre-create is cleared',
            rsrc_name='foo_step1')
        self.client.resources.signal(stack_identifier, 'foo_step1',
                                     data={'unset_hook': 'pre-create'})
        self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-create is cleared',
            rsrc_name='foo_step1')
        self._wait_for_resource_status(
            stack_identifier, 'foo_step2', 'INIT_COMPLETE')
        self.wait_for_event_with_reason(
            stack_identifier,
            reason='CREATE paused until Hook pre-create is cleared',
            rsrc_name='foo_step2')
        self.client.resources.signal(stack_identifier, 'foo_step2',
                                     data={'unset_hook': 'pre-create'})
        self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-create is cleared',
            rsrc_name='foo_step2')
        self._wait_for_resource_status(
            stack_identifier, 'foo_step3', 'INIT_COMPLETE')
        self.wait_for_event_with_reason(
            stack_identifier,
            reason='CREATE paused until Hook pre-create is cleared',
            rsrc_name='foo_step3')
        self.client.resources.signal(stack_identifier, 'foo_step3',
                                     data={'unset_hook': 'pre-create'})
        self.wait_for_event_with_reason(
            stack_identifier,
            reason='Hook pre-create is cleared',
            rsrc_name='foo_step3')
        self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
