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

from oslo_utils import reflection

from heat_integrationtests.common import test


class ScenarioTestsBase(test.HeatIntegrationTest):
    """This class defines common parameters for scenario tests."""

    def setUp(self):
        super(ScenarioTestsBase, self).setUp()
        self.check_skip()
        self.sub_dir = 'templates'
        self.assign_keypair()

        if not self.conf.fixed_network_name:
            raise self.skipException("No default network configured to test")
        self.net = self._get_network()

        if not self.conf.minimal_image_ref:
            raise self.skipException("No minimal image configured to test")
        if not self.conf.minimal_instance_type:
            raise self.skipException("No minimal flavor configured to test")

    def launch_stack(self, template_name, expected_status='CREATE_COMPLETE',
                     parameters=None, **kwargs):
        template = self._load_template(__file__, template_name, self.sub_dir)

        parameters = parameters or {}

        if kwargs.get('add_parameters'):
            parameters.update(kwargs['add_parameters'])

        stack_id = self.stack_create(
            stack_name=kwargs.get('stack_name'),
            template=template,
            files=kwargs.get('files'),
            parameters=parameters,
            environment=kwargs.get('environment'),
            expected_status=expected_status
        )

        return stack_id

    def check_skip(self):
        test_cls_name = reflection.get_class_name(self, fully_qualified=False)
        test_method_name = '.'.join([test_cls_name, self._testMethodName])
        test_skipped = (self.conf.skip_scenario_test_list and (
            test_cls_name in self.conf.skip_scenario_test_list or
            test_method_name in self.conf.skip_scenario_test_list))
        if self.conf.skip_scenario_tests or test_skipped:
            self.skipTest('Test disabled in conf, skipping')
