#    Copyright 2016 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 datetime
import json

from devops import error
from functools32 import lru_cache

from tcp_tests import logger
from tcp_tests import settings


LOG = logger.logger


class RallyManager(object):
    """docstring for RallyManager"""

    image_name = (
        'docker-prod-virtual.docker.mirantis.net/'
        'mirantis/oscore/rally-tempest')
    image_version = 'latest'
    tempest_tag = "16.0.0"
    designate_tag = "0.2.0"

    def __init__(self, underlay, rally_node='gtw01.'):
        super(RallyManager, self).__init__()
        self._underlay = underlay
        self._node_name = self.get_target_node(target=rally_node)

    @property
    @lru_cache(maxsize=None)
    def image_id(self):
        LOG.info("Getting image id")
        cmd = ("docker images | grep {0}| grep {1}| awk '{{print $3}}'"
               .format(self.image_name, self.image_version))
        res = self._underlay.check_call(cmd, node_name=self._node_name)
        LOG.debug(res['stdout'])
        image_id = res['stdout'][0].strip()
        LOG.info("Image ID is {}".format(image_id))
        return image_id

    @property
    @lru_cache(maxsize=None)
    def docker_id(self):
        cmd = ("docker ps | grep {image_id} | "
               "awk '{{print $1}}'| head -1").format(
                   image_id=self.image_id)
        LOG.info("Getting container id")
        res = self._underlay.check_call(cmd, node_name=self._node_name)
        docker_id = res['stdout'][0].strip()
        LOG.info("Container ID is {}".format(docker_id))
        return docker_id

    # Move method to underlay
    def get_target_node(self, target='gtw01.'):
        return [node_name for node_name
                in self._underlay.node_names()
                if node_name.startswith(target)][0]

    def _docker_exec(self, cmd, timeout=None, verbose=False):
        docker_cmd = ('docker exec -i {docker_id} bash -c "{cmd}"'
                      .format(cmd=cmd, docker_id=self.docker_id))
        LOG.info("Executing: {docker_cmd}".format(docker_cmd=docker_cmd))
        return self._underlay.check_call(docker_cmd, node_name=self._node_name,
                                         verbose=verbose, timeout=timeout)

    def _run(self):
        """Start the rally container in the background"""
        with self._underlay.remote(node_name=self._node_name) as remote:
            cmd = ("docker run --net host -v /root/rally:/home/rally/.rally "
                   "-v /etc/ssl/certs/:/etc/ssl/certs/ "
                   "-tid -u root --entrypoint /bin/bash {image_id}"
                   .format(image_id=self.image_id))
            LOG.info("Run Rally container")
            remote.check_call(cmd)

    def run_container(self, version=None):
        """Install docker, configure and run rally container"""
        version = version or self.image_version
        image = self.image_name
        LOG.info("Pull {image}:{version}".format(image=image,
                                                 version=version))
        try:
            cmd = ("apt-get -y install docker-ce &&"
                   " docker pull {image}:{version}".format(image=image,
                                                           version=version))
            self._underlay.check_call(cmd, node_name=self._node_name)
        except Exception as e:
            LOG.debug('Cannot install docker-ce')
            cmd = ("apt-get -y install docker.io &&"
                   " docker pull {image}:{version}".format(image=image,
                                                           version=version))
            self._underlay.check_call(cmd, node_name=self._node_name)

        cmd_iptables = "iptables --policy FORWARD ACCEPT"
        self._underlay.check_call(cmd_iptables, node_name=self._node_name)

        LOG.info("Create rally workdir")
        cmd = 'mkdir -p /root/rally; chown 65500 /root/rally'
        self._underlay.check_call(cmd, node_name=self._node_name)

        LOG.info("Copy keystonercv3")
        tgt = self._node_name.split('.')[0]
        cmd = "scp -3 ctl01:/root/keystonercv3 " \
              "{tgt}:/root/rally/keystonercv3".format(
                  tgt=tgt)
        domain = '.'.join(self._node_name.split('.')[1:])
        self._underlay.check_call(cmd, node_name="cfg01.{domain}".format(
            domain=domain))
        self._run()

        LOG.info("Create rally deployment")
        self._docker_exec("rally-manage db recreate")
        self._docker_exec("source /home/rally/.rally/keystonercv3;"
                          "rally deployment create --fromenv --name=Abathur")
        self._docker_exec("rally deployment list")

    def prepare_rally_task(self, target_node='ctl01.'):
        """Prepare cirros image and private network for rally task"""
        ctl_node_name = self._underlay.get_target_node_names(
            target=target_node)[0]
        cmds = [
            ". keystonercv3 ; openstack flavor create --public m1.tiny",
            ("wget http://download.cirros-cloud.net/0.3.4/"
             "cirros-0.3.4-i386-disk.img"),
            (". /root/keystonercv3; glance --timeout 120 image-create "
             "--name cirros-disk --visibility public --disk-format qcow2 "
             "--container-format bare --progress "
             "< /root/cirros-0.3.4-i386-disk.img"),
            ". /root/keystonercv3; neutron net-create net04",
        ]

        for cmd in cmds:
            self._underlay.check_call(cmd, node_name=ctl_node_name)

    def prepare_tempest_task(self):
        """Configure rally.conf for tempest tests"""
        pass
#        LOG.info("Modify rally.conf")
#        cmd = ("sed -i 's|#swift_operator_role = Member|"
#               "swift_operator_role=SwiftOperator|g' "
#               "/etc/rally/rally.conf")
#        self._docker_exec(cmd)

    def create_rally_task(self, task_path, task_content):
        """Create a file with rally task definition

        :param task_path: path to JSON or YAML file on target node
        :task_content: string with json or yaml content to store in file
        """
        cmd = ("mkdir -p $(dirname {task_path}) && "
               "cat > {task_path} << EOF\n{task_content}\nEOF").format(
            task_path=task_path, task_content=task_content)
        self._underlay.check_call(cmd, node_name=self._node_name)

    def run_task(self, task='', timeout=None, raise_on_timeout=True,
                 verbose=False):
        """Run rally task

        :param taks: path to json or yaml file with the task definition
        :param raise_on_timeout: bool, ignore TimeoutError if False
        :param verbose: show rally output to console if True
        """
        try:
            res = self._docker_exec(
                "rally task start {task}".format(task=task),
                timeout=timeout,
                verbose=verbose)
        except error.TimeoutError:
            if raise_on_timeout:
                raise
            else:
                res = None
                pass
        return res

    # Updated to replace the OpenStackManager method run_tempest
    def run_tempest(self, conf_name='/var/lib/lvm_mcp.conf',
                    pattern='set=smoke', concurrency=0, timeout=None,
                    report_prefix='', report_types=None,
                    designate_plugin=True):
        """Run tempest tests

        :param conf_name: tempest config placed in the rally container
        :param pattern: tempest testcase name or one of existing 'set=...'
        :param concurrency: how many threads to use in parallel. 0 means
                            to take the amount of the cores on the node
                            <self._node_name>.
        :param timeout: stop tempest tests after specified timeout.
        :param designate_plugin: enabled by default plugin for designate
        :param report_prefix: str, prefix for report filenames. Usually the
                              output of the fixture 'func_name'
        :param report_types: list of the report types that need to download
                             from the environment: ['html', 'xml', 'json'].
                             None by default.
        """
        report_types = report_types or []
        if not designate_plugin:
            cmd = (
                "cat > /root/rally/install_tempest.sh << EOF\n"
                "rally verify create-verifier"
                "  --type tempest "
                "  --name tempest-verifier"
                "  --source /var/lib/tempest"
                "  --version {tempest_tag}"
                "  --system-wide\n"
                "rally verify configure-verifier --extend {tempest_conf}\n"
                "rally verify configure-verifier --show\n"
                "EOF".format(tempest_tag=self.tempest_tag,
                             tempest_conf=conf_name))
        else:
            cmd = (
                "cat > /root/rally/install_tempest.sh << EOF\n"
                "rally verify create-verifier"
                "  --type tempest "
                "  --name tempest-verifier"
                "  --source /var/lib/tempest"
                "  --version {tempest_tag}"
                "  --system-wide\n"
                "rally verify add-verifier-ext"
                "  --source /var/lib/designate-tempest-plugin"
                "  --version {designate_tag}\n"
                "rally verify configure-verifier --extend {tempest_conf}\n"
                "rally verify configure-verifier --show\n"
                "EOF".format(tempest_tag=self.tempest_tag,
                             designate_tag=self.designate_tag,
                             tempest_conf=conf_name))
        with self._underlay.remote(node_name=self._node_name) as remote:
            LOG.info("Create install_tempest.sh")
            remote.check_call(cmd)
            remote.check_call("chmod +x /root/rally/install_tempest.sh")

        LOG.info("Run tempest inside Rally container")
        self._docker_exec("/home/rally/.rally/install_tempest.sh")
        self._docker_exec(
            ("source /home/rally/.rally/keystonercv3 && "
             "rally verify start --skip-list /var/lib/mcp_skip.list "
             "  --concurrency {concurrency} --pattern {pattern}"
             .format(concurrency=concurrency, pattern=pattern)),
            timeout=timeout, verbose=True)
        if report_prefix:
            report_filename = '{0}_report_{1}'.format(
                report_prefix,
                datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
        else:
            report_filename = 'report_{1}'.format(
                datetime.datetime.now().strftime('%Y%m%d_%H%M%S'))
        docker_file_prefix = '/home/rally/.rally/' + report_filename

        # Create reports
        if 'xml' in report_types:
            self._docker_exec(
                "rally verify report --type junit-xml --to {0}.xml"
                .format(docker_file_prefix))
        if 'html' in report_types:
            self._docker_exec(
                "rally verify report --type html --to {0}.html"
                .format(docker_file_prefix))
        # Always create report in JSON to return results into test case
        # However, it won't be downloaded until ('json' in report_prefix)
        self._docker_exec("rally verify report --type json --to {0}.json"
                          .format(docker_file_prefix))

        # Download reports to the settings.LOGS_DIR
        file_src_prefix = '/root/rally/{0}'.format(report_filename)
        file_dst_prefix = '{0}/{1}'.format(settings.LOGS_DIR, report_filename)
        with self._underlay.remote(node_name=self._node_name) as remote:
            for suffix in report_types:
                remote.download(file_src_prefix + '.' + suffix,
                                file_dst_prefix + '.' + suffix)
            res = json.load(remote.open(file_src_prefix + '.json'))

        # Get latest verification ID to find the lates testcases in the report
        vtime = {vdata['finished_at']: vid
                 for vid, vdata in res['verifications'].items()}
        vlatest_id = vtime[max(vtime.keys())]

        # Each status has the dict with pairs:
        #   <status>: {
        #       <case_name>: <case_details>,
        #    }
        formatted_tc = {
            'success': {},
            'fail': {},
            'xfail': {},
            'skip': {}
        }

        for tname, tdata in res['tests'].items():
            status = tdata['by_verification'][vlatest_id]['status']
            details = tdata['by_verification'][vlatest_id].get('details', '')
            if status not in formatted_tc:
                # Fail if tempest return a new status that may be
                # necessary to take into account in test cases
                raise Exception("Unknown testcase {0} status: {1} "
                                .format(tname, status))
            formatted_tc[status][tdata['name']] = details
        LOG.debug("Formatted testcases: {0}".format(formatted_tc))
        return formatted_tc
