#    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 junit_xml import TestSuite, TestCase

from tcp_tests import logger
from tcp_tests import settings


LOG = logger.logger


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

    image_name = 'rallyforge/rally'
    image_version = '0.9.1'

    def __init__(self, underlay, admin_host):
        super(RallyManager, self).__init__()
        self._admin_host = admin_host
        self._underlay = underlay

    def prepare(self):
        content = """
sed -i 's|#swift_operator_role = Member|swift_operator_role=SwiftOperator|g' /etc/rally/rally.conf  # noqa
source /home/rally/openrc
rally-manage db recreate
rally deployment create --fromenv --name=tempest
rally verify create-verifier --type tempest --name tempest-verifier
rally verify configure-verifier
rally verify configure-verifier --show
"""
        cmd = "cat > {path} << EOF\n{content}\nEOF".format(
            path='/root/rally/install_tempest.sh', content=content)
        cmd1 = "chmod +x /root/rally/install_tempest.sh"
        cmd2 = "scp ctl01:/root/keystonercv3 /root/rally/openrc"

        with self._underlay.remote(host=self._admin_host) as remote:
            LOG.info("Create rally workdir")
            remote.check_call('mkdir -p /root/rally')
            LOG.info("Create install_tempest.sh")
            remote.check_call(cmd)
            LOG.info("Chmod +x install_tempest.sh")
            remote.check_call(cmd1)
            LOG.info("Copy openstackrc")
            remote.check_call(cmd2)

    def pull_image(self, version=None):
        version = version or self.image_version
        image = self.image_name
        cmd = ("apt-get -y install docker.io &&"
               " docker pull {image}:{version}".format(image=image,
                                                       version=version))
        with self._underlay.remote(host=self._admin_host) as remote:
            LOG.info("Pull {image}:{version}".format(image=image,
                                                     version=version))
            remote.check_call(cmd)

        with self._underlay.remote(host=self._admin_host) as remote:
            LOG.info("Getting image id")
            cmd = "docker images | grep {0}| awk '{print $3}'".format(
                self.image_version)
            res = remote.check_call(cmd)
            self.image_id = res['stdout'][0].strip()
            LOG.info("Image ID is {}".format(self.image_id))

    def run(self):
        with self._underlay.remote(host=self._admin_host) as remote:
            cmd = ("docker run --net host -v /root/rally:/home/rally "
                   "-tid -u root {image_id}".format(image_id=self.image_id))
            LOG.info("Run Rally container")
            remote.check_call(cmd)

            cmd = ("docker ps | grep {image_id} | "
                   "awk '{{print $1}}'| head -1").format(
                       image_id=self.image_id)
            LOG.info("Getting container id")
            res = remote.check_call(cmd)
            self.docker_id = res['stdout'][0].strip()
            LOG.info("Container ID is {}".format(self.docker_id))

    def run_tempest(self, test=''):
        docker_exec = ('docker exec -i {docker_id} bash -c "{cmd}"')
        commands = [
            docker_exec.format(cmd="./install_tempest.sh",
                               docker_id=self.docker_id),
            docker_exec.format(
                cmd="source /home/rally/openrc && "
                    "rally verify start {test}".format(test=test),
                docker_id=self.docker_id),
            docker_exec.format(
                cmd="rally verify report --type json --to result.json",
                docker_id=self.docker_id),
            docker_exec.format(
                cmd="rally verify report --type html --to result.html",
                docker_id=self.docker_id),
        ]
        with self._underlay.remote(host=self._admin_host) as remote:
            LOG.info("Run tempest inside Rally container")
            for cmd in commands:
                remote.check_call(cmd, verbose=True)

    def get_results(self, store=True, store_file='tempest.xml'):
        LOG.info('Storing tests results...')
        res_file_name = 'result.json'
        file_prefix = 'results_' + datetime.datetime.now().strftime(
            '%Y%m%d_%H%M%S') + '_'
        file_dst = '{0}/{1}{2}'.format(
            settings.LOGS_DIR, file_prefix, res_file_name)
        with self._underlay.remote(host=self._admin_host) as remote:
            remote.download(
                '/root/rally/{0}'.format(res_file_name),
                file_dst)
            res = json.load(remote.open('/root/rally/result.json'))
        if not store:
            return res

        formatted_tc = []
        failed_cases = [res['test_cases'][case]
                        for case in res['test_cases']
                        if res['test_cases'][case]['status']
                        in 'fail']
        for case in failed_cases:
            if case:
                tc = TestCase(case['name'])
                tc.add_failure_info(case['traceback'])
                formatted_tc.append(tc)

        skipped_cases = [res['test_cases'][case]
                         for case in res['test_cases']
                         if res['test_cases'][case]['status'] in 'skip']
        for case in skipped_cases:
            if case:
                tc = TestCase(case['name'])
                tc.add_skipped_info(case['reason'])
                formatted_tc.append(tc)

        error_cases = [res['test_cases'][case] for case in res['test_cases']
                       if res['test_cases'][case]['status'] in 'error']

        for case in error_cases:
            if case:
                tc = TestCase(case['name'])
                tc.add_error_info(case['traceback'])
                formatted_tc.append(tc)

        success = [res['test_cases'][case] for case in res['test_cases']
                   if res['test_cases'][case]['status'] in 'success']
        for case in success:
            if case:
                tc = TestCase(case['name'])
                formatted_tc.append(tc)

        ts = TestSuite("tempest", formatted_tc)
        with open(store_file, 'w') as f:
            ts.to_file(f, [ts], prettyprint=False)

        return res
