#    Copyright 2018 Mirantis, 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 json
import os

from tcp_tests import logger
from tcp_tests import settings

LOG = logger.logger

TEMPEST_CFG_DIR = '/tmp/test'


class RuntestManager(object):
    """Helper manager for execution tempest via runtest-formula"""

    image_name = settings.TEMPEST_IMAGE
    image_version = settings.TEMPEST_IMAGE_VERSION
    container_name = 'run-tempest-ci'
    master_host = "cfg01"
    control_host = "ctl01"
    class_name = "runtest"
    run_cmd = '/bin/bash -c "run-tempest"'

    def __init__(self, config, underlay, salt_api, cluster_name,
                 domain_name, tempest_threads,
                 tempest_pattern=settings.TEMPEST_PATTERN,
                 run_cmd=None, target='gtw01'):
        self.__config = config
        self.underlay = underlay
        self.__salt_api = salt_api
        self.cluster_name = cluster_name
        self.domain_name = domain_name
        self.tempest_threads = tempest_threads
        self.tempest_pattern = tempest_pattern
        self.run_cmd = run_cmd or self.run_cmd
        self.target_name = self.underlay.get_target_node_names(target)[0]
        self.master_name = self.underlay.get_target_node_names(
            self.master_host)[0]
        self.control_name = self.underlay.get_target_node_names(
            self.control_host)[0]

    @property
    def salt_api(self):
        return self.__salt_api

    @property
    def runtest_pillar(self):
        public_net = self.__config.underlay.dhcp_ranges[
            settings.EXTERNAL_ADDRESS_POOL_NAME]
        public_gateway = public_net["gateway"].encode("ascii")
        public_cidr = public_net["cidr"].encode("ascii")
        public_allocation_start = public_net["start"].encode("ascii")
        public_allocation_end = public_net["end"].encode("ascii")

        return {
            'classes': ['service.runtest.tempest',
                        'service.runtest.tempest.public_net',
                        'service.runtest.tempest.services.manila.glance'],
            'parameters': {
                '_param': {
                    'runtest_tempest_cfg_dir': TEMPEST_CFG_DIR,
                    'runtest_tempest_cfg_name': 'tempest.conf',
                    'runtest_tempest_public_net': 'public',
                    'openstack_public_neutron_subnet_gateway': public_gateway,
                    'openstack_public_neutron_subnet_cidr': public_cidr,
                    'openstack_public_neutron_subnet_allocation_start':
                        public_allocation_start,
                    'openstack_public_neutron_subnet_allocation_end':
                        public_allocation_end,
                    'tempest_test_target': self.target_name.encode("ascii"),
                },
                'neutron': {
                    'client': {
                        'enabled': True
                    }
                },
                'runtest': {
                    'enabled': True,
                    'keystonerc_node': 'ctl01*',
                    'tempest': {
                        'enabled': True,
                        'cfg_dir': '${_param:runtest_tempest_cfg_dir}',
                        'cfg_name': '${_param:runtest_tempest_cfg_name}',
                        'DEFAULT': {
                            'log_file': 'tempest.log'
                        },
                        'compute': {
                            'min_compute_nodes': 2,
                        },
                        'convert_to_uuid': {
                            'network': {
                                'public_network_id':
                                '${_param:runtest_tempest_public_net}'
                            }
                        },
                        'share': {
                            'capability_snapshot_support': True,
                            'run_driver_assisted_migration_tests': False,
                            'run_manage_unmanage_snapshot_tests': False,
                            'run_manage_unmanage_tests': False,
                            'run_migration_with_preserve_snapshots_tests':
                                False,
                            'run_quota_tests': True,
                            'run_replication_tests': False,
                            'run_snapshot_tests': True,
                        }}}}}

    def fetch_arficats(self, username=None, file_format='xml'):
        with self.underlay.remote(node_name=self.target_name,
                                  username=None) as tgt:
            result = tgt.execute('find {} -name "report_*.{}"'.format(
                TEMPEST_CFG_DIR, file_format))
            LOG.debug("Find result {0}".format(result))
            assert len(result['stdout']) > 0, ('No report found, please check'
                                               ' if test run was successful.')
            report = result['stdout'][0].rstrip()
            LOG.debug("Found files {0}".format(report))
            tgt.download(
                destination=report,  # noqa
                target=os.getcwd())

    def store_runtest_model(self, runtest_pillar=None):
        with self.underlay.yaml_editor(
                file_path="/srv/salt/reclass/classes/cluster/"
                          "{cluster_name}/infra/"
                          "{class_name}.yml".format(
                              cluster_name=self.cluster_name,
                              class_name=self.class_name),
                node_name=self.master_name) as editor:
            editor.content = runtest_pillar or self.runtest_pillar
        with self.underlay.yaml_editor(
                file_path="/srv/salt/reclass/nodes/_generated/"
                          "cfg01.{domain_name}.yml".format(
                              domain_name=self.domain_name),
                node_name=self.master_name) as editor:
            editor.content['classes'].append(
                'cluster.{cluster_name}.infra.{class_name}'.format(
                    cluster_name=self.cluster_name,
                    class_name=self.class_name))

    def save_runtime_logs(self, logs=None, inspect=None):
        if logs:
            with open("{path}/{target}_tempest_run.log".format(
                    path=settings.LOGS_DIR,
                    target=self.target_name), 'w') as f:
                LOG.info("Save tempest console log")
                container_log = logs
                f.write(container_log.encode('ascii', 'ignore'))

        if inspect:
            with open("{path}/{target}_tempest_container_info.json.log".format(
                    path=settings.LOGS_DIR,
                    target=self.target_name), 'w') as f:
                LOG.info("Save tempest container inspect data")

                container_inspect = json.dumps(inspect,
                                               indent=4, sort_keys=True)
                f.write(container_inspect)

    def prepare(self, dpdk=None):
        self.store_runtest_model()

        salt_cmd = "salt -l info --hard-crash --state-output=mixed "
        salt_call_cmd = "salt-call -l info --hard-crash --state-output=mixed "
        commands = [
            {
                'description': "Sync salt objects for runtest model",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_cmd + "'*' saltutil.refresh_pillar && " +
                        salt_cmd + "'*' saltutil.sync_all")},
            {
                'description': ("Install docker.io package and "
                                "enable packets forwarding"),
                'node_name': self.target_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " pkg.install docker.io && " +
                        " iptables --policy FORWARD ACCEPT")},
            {
                'description': "Install PyPI docker package",
                'node_name': self.target_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " pip.install setuptools && " +
                        salt_call_cmd + " pip.install docker")},
            {
                'description': "Run salt.minion state for runtest formula",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " state.sls salt.minion && "
                        " sleep 20")},
            {
                'description': "Enforce keystone state for neutronv2",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " state.sls keystone.client")},
            {
                'description': "Create networks for Tempest tests",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " state.sls neutron.client")},
            {
                'description': "Create flavors for Tempest tests",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " state.sls nova.client")},
            {
                'description': "Create cirros image for Tempest",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " state.sls glance.client")},
            {
                'description': "Generate config for Tempest",
                'node_name': self.master_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " state.sls runtest")},
        ]

        if dpdk:
            commands.append({
                'description': "Configure flavor for DPDK",
                'node_name': self.control_name,
                'cmd': ("set -ex;" +
                        salt_call_cmd + " cmd.run "
                        " '. /root/keystonercv3;"
                        "  openstack flavor set m1.tiny_test"
                        "  --property hw:mem_page_size=small'")},
            )

        self.__salt_api.execute_commands(commands=commands,
                                         label="Prepare for Tempest")

    def run_tempest(self, timeout=600):
        tgt = self.target_name
        image_nameversion = "{}:{}".format(self.image_name, self.image_version)

        docker_args = (
            " --name {container_name} "
            " -e ARGS=\"-r {tempest_pattern} -w {tempest_threads}\""
            " -v {cfg_dir}/tempest.conf:/etc/tempest/tempest.conf"
            " -v /tmp/:/tmp/"
            " -v {cfg_dir}:/root/tempest"
            " -v /etc/ssl/certs/:/etc/ssl/certs/"
            " --rm"
            " {image_nameversion} {run_cmd}"
            .format(
                container_name=self.container_name,
                image_nameversion=image_nameversion,
                tempest_pattern=self.tempest_pattern,
                tempest_threads=self.tempest_threads,
                cfg_dir=TEMPEST_CFG_DIR,
                run_cmd=self.run_cmd,
            ))

        commands = [
            {
                'description': "Run Tempest tests {0}".format(
                    image_nameversion),
                'node_name': self.target_name,
                'cmd': ("set -ex;" +
                        " docker rm --force {container_name} || true;"
                        " docker run {docker_args}"
                        .format(container_name=self.container_name,
                                docker_args=docker_args)),
                'timeout': timeout},
        ]

        self.__salt_api.execute_commands(commands=commands,
                                         label="Run Tempest tests")

        inspect_res = self.salt_api.local(tgt,
                                          'dockerng.inspect',
                                          self.container_name)
        inspect = inspect_res['return'][0]
        inspect = next(inspect.iteritems())[1]
        logs_res = self.salt_api.local(tgt,
                                       'dockerng.logs',
                                       self.container_name)
        logs = logs_res['return'][0]
        logs = next(logs.iteritems())[1]

        res = self.salt_api.local(tgt, 'dockerng.rm', self.container_name)
        LOG.info("Tempest container was removed".format(
            json.dumps(res, indent=4)))

        return {'inspect': inspect,
                'logs': logs}

    def prepare_and_run_tempest(self, username='root', dpdk=None):
        """
        Run tempest tests
        """
        tempest_timeout = settings.TEMPEST_TIMEOUT
        self.prepare(dpdk=dpdk)
        test_res = self.run_tempest(tempest_timeout)
        self.fetch_arficats(username=username)
        self.save_runtime_logs(**test_res)
