# Copyright (C) 2017 Red Hat, 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.

import os
import shutil
import tempfile
import unittest

from devstack_local_conf import LocalConf
from collections import OrderedDict

class TestDevstackLocalConf(unittest.TestCase):

    @staticmethod
    def _init_localconf(p):
        lc = LocalConf(p.get('localrc'),
                       p.get('local_conf'),
                       p.get('base_services'),
                       p.get('services'),
                       p.get('plugins'),
                       p.get('base_dir'),
                       p.get('projects'),
                       p.get('project'),
                       p.get('tempest_plugins'))
        return lc

    def setUp(self):
        self.tmpdir = tempfile.mkdtemp()

    def tearDown(self):
        shutil.rmtree(self.tmpdir)

    def test_plugins(self):
        "Test that plugins without dependencies work"
        localrc = {'test_localrc': '1'}
        local_conf = {'install':
                      {'nova.conf':
                       {'main':
                        {'test_conf': '2'}}}}
        services = {'cinder': True}
        # We use ordereddict here to make sure the plugins are in the
        # *wrong* order for testing.
        plugins = OrderedDict([
            ('bar', 'https://git.openstack.org/openstack/bar-plugin'),
            ('foo', 'https://git.openstack.org/openstack/foo-plugin'),
            ('baz', 'https://git.openstack.org/openstack/baz-plugin'),
            ])
        p = dict(localrc=localrc,
                 local_conf=local_conf,
                 base_services=[],
                 services=services,
                 plugins=plugins,
                 base_dir='./test',
                 path=os.path.join(self.tmpdir, 'test.local.conf'))
        lc = self._init_localconf(p)
        lc.write(p['path'])

        plugins = []
        with open(p['path']) as f:
            for line in f:
                if line.startswith('enable_plugin'):
                    plugins.append(line.split()[1])
        self.assertEqual(['bar', 'baz', 'foo'], plugins)


    def test_plugin_deps(self):
        "Test that plugins with dependencies work"
        os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', 'devstack'))
        os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', '.git'))
        os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', 'devstack'))
        os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', '.git'))
        with open(os.path.join(
                self.tmpdir,
                'foo-plugin', 'devstack', 'settings'), 'w') as f:
            f.write('define_plugin foo-plugin\n')
        with open(os.path.join(
                self.tmpdir,
                'bar-plugin', 'devstack', 'settings'), 'w') as f:
            f.write('define_plugin bar-plugin\n')
            f.write('plugin_requires bar-plugin foo-plugin\n')

        localrc = {'test_localrc': '1'}
        local_conf = {'install':
                      {'nova.conf':
                       {'main':
                        {'test_conf': '2'}}}}
        services = {'cinder': True}
        # We use ordereddict here to make sure the plugins are in the
        # *wrong* order for testing.
        plugins = OrderedDict([
            ('bar-plugin', 'https://git.openstack.org/openstack/bar-plugin'),
            ('foo-plugin', 'https://git.openstack.org/openstack/foo-plugin'),
            ])
        p = dict(localrc=localrc,
                 local_conf=local_conf,
                 base_services=[],
                 services=services,
                 plugins=plugins,
                 base_dir=self.tmpdir,
                 path=os.path.join(self.tmpdir, 'test.local.conf'))
        lc = self._init_localconf(p)
        lc.write(p['path'])

        plugins = []
        with open(p['path']) as f:
            for line in f:
                if line.startswith('enable_plugin'):
                    plugins.append(line.split()[1])
        self.assertEqual(['foo-plugin', 'bar-plugin'], plugins)

    def test_libs_from_git(self):
        "Test that LIBS_FROM_GIT is auto-generated"
        projects = {
            'git.openstack.org/openstack/nova': {
                'required': True,
                'short_name': 'nova',
            },
            'git.openstack.org/openstack/oslo.messaging': {
                'required': True,
                'short_name': 'oslo.messaging',
            },
            'git.openstack.org/openstack/devstack-plugin': {
                'required': False,
                'short_name': 'devstack-plugin',
            },
        }
        project = {
            'short_name': 'glance',
        }
        p = dict(base_services=[],
                 base_dir='./test',
                 path=os.path.join(self.tmpdir, 'test.local.conf'),
                 projects=projects,
                 project=project)
        lc = self._init_localconf(p)
        lc.write(p['path'])

        lfg = None
        with open(p['path']) as f:
            for line in f:
                if line.startswith('LIBS_FROM_GIT'):
                    lfg = line.strip().split('=')[1]
        self.assertEqual('nova,oslo.messaging,glance', lfg)

    def test_overridelibs_from_git(self):
        "Test that LIBS_FROM_GIT can be overridden"
        localrc = {'LIBS_FROM_GIT': 'oslo.db'}
        projects = {
            'git.openstack.org/openstack/nova': {
                'required': True,
                'short_name': 'nova',
            },
            'git.openstack.org/openstack/oslo.messaging': {
                'required': True,
                'short_name': 'oslo.messaging',
            },
            'git.openstack.org/openstack/devstack-plugin': {
                'required': False,
                'short_name': 'devstack-plugin',
            },
        }
        p = dict(localrc=localrc,
                 base_services=[],
                 base_dir='./test',
                 path=os.path.join(self.tmpdir, 'test.local.conf'),
                 projects=projects)
        lc = self._init_localconf(p)
        lc.write(p['path'])

        lfg = None
        with open(p['path']) as f:
            for line in f:
                if line.startswith('LIBS_FROM_GIT'):
                    lfg = line.strip().split('=')[1]
        self.assertEqual('oslo.db', lfg)

    def test_plugin_circular_deps(self):
        "Test that plugins with circular dependencies fail"
        os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', 'devstack'))
        os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', '.git'))
        os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', 'devstack'))
        os.makedirs(os.path.join(self.tmpdir, 'bar-plugin', '.git'))
        with open(os.path.join(
                self.tmpdir,
                'foo-plugin', 'devstack', 'settings'), 'w') as f:
            f.write('define_plugin foo\n')
            f.write('plugin_requires foo bar\n')
        with open(os.path.join(
                self.tmpdir,
                'bar-plugin', 'devstack', 'settings'), 'w') as f:
            f.write('define_plugin bar\n')
            f.write('plugin_requires bar foo\n')

        localrc = {'test_localrc': '1'}
        local_conf = {'install':
                      {'nova.conf':
                       {'main':
                        {'test_conf': '2'}}}}
        services = {'cinder': True}
        # We use ordereddict here to make sure the plugins are in the
        # *wrong* order for testing.
        plugins = OrderedDict([
            ('bar', 'https://git.openstack.org/openstack/bar-plugin'),
            ('foo', 'https://git.openstack.org/openstack/foo-plugin'),
            ])
        p = dict(localrc=localrc,
                 local_conf=local_conf,
                 base_services=[],
                 services=services,
                 plugins=plugins,
                 base_dir=self.tmpdir,
                 path=os.path.join(self.tmpdir, 'test.local.conf'))
        with self.assertRaises(Exception):
            lc = self._init_localconf(p)
            lc.write(p['path'])

    def _find_tempest_plugins_value(self, file_path):
        tp = None
        with open(file_path) as f:
            for line in f:
                if line.startswith('TEMPEST_PLUGINS'):
                    found = line.strip().split('=')[1]
                    self.assertIsNone(tp,
                        "TEMPEST_PLUGIN ({}) found again ({})".format(
                            tp, found))
                    tp = found
        return tp

    def test_tempest_plugins(self):
        "Test that TEMPEST_PLUGINS is correctly populated."
        p = dict(base_services=[],
                 base_dir='./test',
                 path=os.path.join(self.tmpdir, 'test.local.conf'),
                 tempest_plugins=['heat-tempest-plugin', 'sahara-tests'])
        lc = self._init_localconf(p)
        lc.write(p['path'])

        tp = self._find_tempest_plugins_value(p['path'])
        self.assertEqual('"./test/heat-tempest-plugin ./test/sahara-tests"', tp)
        self.assertEqual(len(lc.warnings), 0)

    def test_tempest_plugins_not_overridden(self):
        """Test that the existing value of TEMPEST_PLUGINS is not overridden
        by the user-provided value, but a warning is emitted."""
        localrc = {'TEMPEST_PLUGINS': 'someplugin'}
        p = dict(localrc=localrc,
                 base_services=[],
                 base_dir='./test',
                 path=os.path.join(self.tmpdir, 'test.local.conf'),
                 tempest_plugins=['heat-tempest-plugin', 'sahara-tests'])
        lc = self._init_localconf(p)
        lc.write(p['path'])

        tp = self._find_tempest_plugins_value(p['path'])
        self.assertEqual('someplugin', tp)
        self.assertEqual(len(lc.warnings), 1)


if __name__ == '__main__':
    unittest.main()
