"""
Module for jenkinsapi views
"""
import six
import logging

from jenkinsapi.jenkinsbase import JenkinsBase
from jenkinsapi.job import Job
from jenkinsapi.custom_exceptions import NotFound


log = logging.getLogger(__name__)


class View(JenkinsBase):

    """
    View class
    """

    def __init__(self, url, name, jenkins_obj):
        self.name = name
        self.jenkins_obj = jenkins_obj
        JenkinsBase.__init__(self, url)
        self.deleted = False

    def __str__(self):
        return self.name

    def __getitem__(self, job_name):
        assert isinstance(job_name, str)
        api_url = self.python_api_url(self.get_job_url(job_name))
        return Job(api_url, job_name, self.jenkins_obj)

    def __contains__(self, job_name):
        """
        True if view_name is the name of a defined view
        """
        return job_name in self.keys()

    def delete(self):
        """
        Remove this view object
        """
        url = "%s/doDelete" % self.baseurl
        self.jenkins_obj.requester.post_and_confirm_status(url, data='')
        self.jenkins_obj.poll()
        self.deleted = True

    def keys(self):
        return self.get_job_dict().keys()

    def iteritems(self):
        it = six.iteritems(self.get_job_dict())

        for name, url in it:
            yield name, Job(url, name, self.jenkins_obj)

    def values(self):
        return [a[1] for a in self.iteritems()]

    def items(self):
        return [a for a in self.iteritems()]

    def _get_jobs(self):
        if 'jobs' in self._data:
            for viewdict in self._data["jobs"]:
                yield viewdict["name"], viewdict["url"]

    def get_job_dict(self):
        return dict(self._get_jobs())

    def __len__(self):
        return len(self.get_job_dict().keys())

    def get_job_url(self, str_job_name):
        if str_job_name in self:
            return self.get_job_dict()[str_job_name]
        else:
            # noinspection PyUnboundLocalVariable
            views_jobs = ", ".join(self.get_job_dict().keys())
            raise NotFound("Job %s is not known, available jobs"
                           " in view are: %s" % (str_job_name, views_jobs))

    def get_jenkins_obj(self):
        return self.jenkins_obj

    def add_job(self, str_job_name, job=None):
        """
        Add job to a view

        :param str_job_name: name of the job to be added
        :param job: Job object to be added
        :return: True if job has been added, False if job already exists or
         job not known to Jenkins
        """
        if not job:
            if str_job_name in self.get_job_dict():
                log.warning(
                    'Job %s is already in the view %s',
                    str_job_name, self.name)
                return False
            else:
                # Since this call can be made from nested view,
                # which doesn't have any jobs, we can miss existing job
                # Thus let's create top level Jenkins and ask him
                # http://jenkins:8080/view/CRT/view/CRT-FB/view/CRT-SCRT-1301/
                top_jenkins = self.get_jenkins_obj().get_jenkins_obj_from_url(
                    self.baseurl.split('view/')[0])
                if not top_jenkins.has_job(str_job_name):
                    log.error(
                        msg='Job "%s" is not known to Jenkins' %
                        str_job_name)
                    return False
                else:
                    job = top_jenkins.get_job(str_job_name)

        log.info(msg='Creating job %s in view %s' % (str_job_name, self.name))

        url = '%s/addJobToView' % self.baseurl
        params = {'name': str_job_name}

        self.get_jenkins_obj().requester.post_and_confirm_status(
            url,
            data={},
            params=params)
        self.poll()
        log.debug(msg='Job "%s" has been added to a view "%s"' %
                  (job.name, self.name))
        return True

    def _get_nested_views(self):
        for viewdict in self._data.get("views", []):
            yield viewdict["name"], viewdict["url"]

    def get_nested_view_dict(self):
        return dict(self._get_nested_views())

    def get_config_xml_url(self):
        return '%s/config.xml' % self.baseurl

    def get_config(self):
        """
        Return the config.xml from the view
        """
        url = self.get_config_xml_url()
        response = self.get_jenkins_obj().requester.get_and_confirm_status(url)
        return response.text

    def update_config(self, config):
        """
        Update the config.xml to the view
        """
        url = self.get_config_xml_url()
        config = str(config)  # cast unicode in case of Python 2

        response = self.get_jenkins_obj().requester.post_url(
            url, params={}, data=config)
        return response.text

    @property
    def views(self):
        return self.get_jenkins_obj().get_jenkins_obj_from_url(
            self.baseurl).views

[((12, 6, 12, 33), 'logging.getLogger', 'logging.getLogger', ({(12, 24, 12, 32): '__name__'}, {}), '(__name__)', False, 'import logging\n'), ((24, 8, 24, 39), 'jenkinsapi.jenkinsbase.JenkinsBase.__init__', 'JenkinsBase.__init__', ({(24, 29, 24, 33): 'self', (24, 35, 24, 38): 'url'}, {}), '(self, url)', False, 'from jenkinsapi.jenkinsbase import JenkinsBase\n'), ((33, 15, 33, 55), 'jenkinsapi.job.Job', 'Job', ({(33, 19, 33, 26): 'api_url', (33, 28, 33, 36): 'job_name', (33, 38, 33, 54): 'self.jenkins_obj'}, {}), '(api_url, job_name, self.jenkins_obj)', False, 'from jenkinsapi.job import Job\n'), ((82, 18, 83, 75), 'jenkinsapi.custom_exceptions.NotFound', 'NotFound', ({(82, 27, 83, 74): "('Job %s is not known, available jobs in view are: %s' % (str_job_name,\n    views_jobs))"}, {}), "('Job %s is not known, available jobs in view are: %s' % (\n    str_job_name, views_jobs))", False, 'from jenkinsapi.custom_exceptions import NotFound\n'), ((57, 24, 57, 56), 'jenkinsapi.job.Job', 'Job', ({(57, 28, 57, 31): 'url', (57, 33, 57, 37): 'name', (57, 39, 57, 55): 'self.jenkins_obj'}, {}), '(url, name, self.jenkins_obj)', False, 'from jenkinsapi.job import Job\n')]