#    Copyright 2017 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.

from tcp_tests.managers.execute_commands import ExecuteCommandsMixin
from tcp_tests.utils import run_jenkins_job
from tcp_tests.utils import get_jenkins_job_stages
from tcp_tests import logger

LOG = logger.logger


class DrivetrainManager(ExecuteCommandsMixin):
    """docstring for DrivetrainManager"""

    __config = None
    __underlay = None

    def __init__(self, config, underlay, salt=None):
        self.__config = config
        self.__underlay = underlay
        self._salt = salt
        super(DrivetrainManager, self).__init__(
            config=config, underlay=underlay)

    def install(self, commands):
        self.execute_commands(commands,
                              label='Install Drivetrain Tools')
        self.__config.drivetrain.drivetrain_installed = True

    def start_job_on_jenkins(
            self,
            job_name,
            jenkins_tgt='I@docker:client:stack:jenkins and cid01*',
            **kwargs):
        """
        Starts job with specific parameters on cluster Jenkins

        Method accept any param:
            job_parameters=None,
            job_output_prefix='',
            jenkins_tgt='I@salt:master' or
              'I@docker:client:stack:jenkins and cid01*'
            start_timeout=1800,
            build_timeout=3600 * 4,
            verbose=False

        :param job_name: string
        :param jenkins_tgt: string,  node to run jenkins in salt-style
        :return: string, Result of passed job, "SUCCESS"| "FAILED" | "UNSTABLE"
        """
        jenkins_url, jenkins_user, jenkins_pass = self.get_jenkins_creds(
            tgt=jenkins_tgt)

        job_result = run_jenkins_job.run_job(
            host=jenkins_url,
            username=jenkins_user,
            password=jenkins_pass,
            job_name=job_name,
            **kwargs)

        (description, stages) = get_jenkins_job_stages.get_deployment_result(
            host=jenkins_url,
            username=jenkins_user,
            password=jenkins_pass,
            job_name=job_name,
            build_number='lastBuild')

        LOG.info(description)
        LOG.info('\n'.join(stages))

        job_description = "{description}. \n\n{stages}"\
            .format(description=description,
                    stages='\n'.join(stages))

        if job_result != 'SUCCESS':
            LOG.warning("{0}\n{1}".format(description, '\n'.join(stages)))
        return job_result, job_description

    def get_jenkins_creds(self, tgt):
        """
        Requests Jenkins's login parameters from pillars from desired node

        :return: tuple {jenkins_url, jenkins_user, jenkins_pass}
        """
        jenkins_host = self._salt.get_single_pillar(
            tgt=tgt, pillar="jenkins:client:master:host")
        if jenkins_host is None:
            raise Exception(
                "Can't find 'jenkins:client:master' pillar on {tgt} node."
                .format(tgt=tgt))
        jenkins_port = self._salt.get_single_pillar(
            tgt=tgt, pillar="jenkins:client:master:port")
        jenkins_protocol = self._salt.get_single_pillar(
            tgt=tgt, pillar="jenkins:client:master:proto")
        jenkins_url = '{0}://{1}:{2}'.format(jenkins_protocol,
                                             jenkins_host,
                                             jenkins_port)
        jenkins_user = self._salt.get_single_pillar(
            tgt=tgt, pillar="jenkins:client:master:username")
        jenkins_pass = self._salt.get_single_pillar(
            tgt=tgt, pillar="jenkins:client:master:password")
        return jenkins_url, jenkins_user, jenkins_pass
