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