# -*- coding: utf-8 -*-

# Import Python libs
from __future__ import absolute_import
import difflib
import logging

# Import Salt libs
import salt.ext.six as six
import salt.utils

# Import XML parser
import xml.etree.ElementTree as ET
import hashlib

# Jenkins
try:
    import jenkins
    HAS_JENKINS = True
except ImportError:
    HAS_JENKINS = False

log = logging.getLogger(__name__)


def __virtual__():
    '''
    Only load if jenkins_common module exist.
    '''
    if not HAS_JENKINS:
        return (
            False,
            'The jenkins_job state module cannot be loaded: '
            'python Jenkins API client could not be imported')
    if 'jenkins_common.call_groovy_script' not in __salt__:
        return (
            False,
            'The jenkins_job state module cannot be loaded: '
            'jenkins_common not found')
    return True


def _elements_equal(e1, e2):
    return hashlib.md5(e1).hexdigest() == hashlib.md5(e2).hexdigest()


def present(name,
            config=None,
            **kwargs):
    '''
    Ensure the job is present in the Jenkins
    configured jobs
    name
        The unique name for the Jenkins job
    config
        The Salt URL for the file to use for
        configuring the job.
    '''
    test = __opts__['test']
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': ['Job {0} is up to date.'.format(name)]}
    if test:
        status = 'CREATED'
        ret['changes'][name] = status
        ret['comment'] = 'Job %s %s' % (name, status.lower())
    else:
        _current_job_config = ''
        _job_exists = True
        try:
            _current_job_config = __salt__['jenkins.get_job_config'](name)
        except Exception as e:
            if 'does not exist' in str(e):
                _job_exists = False
            else:
                raise e

        if _job_exists:
            buf = six.moves.StringIO(_current_job_config)
            oldXMLstring = buf.read()

            cached_source_path = __salt__['cp.cache_file'](config, __env__)
            with salt.utils.fopen(cached_source_path) as _fp:
                newXMLstring = _fp.read()
            if not _elements_equal(oldXMLstring.strip(), newXMLstring.strip()):
                oldXML = ET.fromstring(oldXMLstring)
                newXML = ET.fromstring(newXMLstring)
                diff = difflib.unified_diff(
                    ET.tostringlist(oldXML, encoding='utf8', method='xml'),
                    ET.tostringlist(newXML, encoding='utf8', method='xml'), lineterm='')
                __salt__['jenkins.update_job'](name, config, __env__)
                ret['changes'][name] = ''.join(diff)
                ret['comment'].append('Job {0} updated.'.format(name))

        else:
            cached_source_path = __salt__['cp.cache_file'](config, __env__)
            with salt.utils.fopen(cached_source_path) as _fp:
                new_config_xml = _fp.read()

            __salt__['jenkins.create_job'](name, config, __env__)

            buf = six.moves.StringIO(new_config_xml)
            diff = difflib.unified_diff('', buf.readlines(), lineterm='')
            ret['changes'][name] = ''.join(diff)
            ret['comment'].append('Job {0} added.'.format(name))

        ret['comment'] = '\n'.join(ret['comment'])
    return ret


def absent(name,
           **kwargs):
    '''
    Ensure the job is present in the Jenkins
    configured jobs

    name
        The name of the Jenkins job to remove.

    '''
    test = __opts__['test']
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': []}
    if test:
        status = 'DELETED'
        ret['changes'][name] = status
        ret['comment'] = 'Node %s %s' % (name, status.lower())
    else:
        _job_exists = __salt__['jenkins.job_exists'](name)

        if _job_exists:
            __salt__['jenkins.delete_job'](name)
            ret['comment'] = 'Job {0} deleted.'.format(name)
        else:
            ret['comment'] = 'Job {0} already absent.'.format(name)
    return ret


def cleanup(name, jobs, **kwargs):
    '''
    Perform a cleanup - uninstall any installed job absents in given jobs list

    name
        The name of the Jenkins job to remove.
    jobs
        List of jobs which may NOT be uninstalled

    '''
    test = __opts__['test']
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': "Cleanup not necessary"}
    list_jobs_groovy = """\
        print(Jenkins.instance.items.collect{it -> it.name})
    """
    deleted_jobs = []
    if test:
        status = 'CLEANED'
        ret['changes'][name] = status
        ret['comment'] = 'Jobs %s' % status.lower()
    else:
        call_result = __salt__['jenkins_common.call_groovy_script'](
            list_jobs_groovy, {})
        if call_result["code"] == 200:
            existing_jobs = call_result["msg"]
            if existing_jobs:
                for job in existing_jobs[1:-1].split(","):
                    if job:
                        job = job.strip()
                        if job not in jobs:
                            __salt__['jenkins.delete_job'](job)
                            deleted_jobs.append(job)
            else:
                log.error("Cannot get existing jobs list from Jenkins")
            if len(deleted_jobs) > 0:
                for del_job in deleted_jobs:
                    ret['changes'][del_job] = "removed"
                ret['comment'] = 'Jobs {} deleted.'.format(deleted_jobs)
        else:
            status = 'FAILED'
            log.error(
                "Jenkins jobs API call failure: %s", call_result["msg"])
            ret['comment'] = 'Jenkins jobs API call failure: %s' % (
                call_result["msg"])
    return ret
