import logging

from salt.exceptions import SaltInvocationError
from string import Template

try:
    import bcrypt
    HAS_BCRYPT = True
except ImportError:
    HAS_BCRYPT = False

try:
    import requests
    HAS_REQUESTS = True
except ImportError:
    HAS_REQUESTS = False

logger = logging.getLogger(__name__)


def __virtual__():
    '''
    Only load if bcrypt and requests libraries exist.
    '''
    if not HAS_BCRYPT:
        return (
            False,
            'Can not load module jenkins_common: bcrypt library not found')
    if not HAS_REQUESTS:
        return (
            False,
            'Can not load module jenkins_common: requests library not found')
    return True


def call_groovy_script(script, props, username=None,
                       password=None, success_status_codes=[200]):
    """
    Common method for call Jenkins groovy script API

    :param script: groovy script template
    :param props: groovy script properties
    :param username: jenkins username (optional,
            if missing creds from sall will be used)
    :param password: jenkins password (optional,
            if missing creds from sall will be used)
    :param success_status_codes: success response status code
            (optional) in some cases we want to declare error call as success
    :returns: HTTP dict {status,code,msg}
    """
    ret = {
        "status": "FAILED",
        "code": 999,
        "msg": ""
    }
    jenkins_url, jenkins_user, jenkins_password = get_jenkins_auth()
    if username:
        jenkins_user = username
    if password:
        jenkins_password = password

    if not jenkins_url:
        raise SaltInvocationError('No Jenkins URL found.')

    token_obj, req_cookies = get_api_crumb(jenkins_url, jenkins_user, jenkins_password)
    req_data = {"script": render_groovy_script(script, props)}
    if token_obj:
        req_data[token_obj["crumbRequestField"]] = token_obj["crumb"]

    logger.debug("Calling Jenkins script API with URL: %s", jenkins_url)
    req = requests.post('%s/scriptText' % jenkins_url,
                        auth=(jenkins_user, jenkins_password) if jenkins_user else None,
                        data=req_data, cookies=req_cookies)
    ret["code"] = req.status_code
    ret["msg"] = req.text
    if req.status_code in success_status_codes:
        ret["status"] = "SUCCESS"
        logger.debug("Jenkins script API call success: %s", ret)
    else:
        logger.error("Jenkins script API call failed. \
            Return code %s. Text: %s", req.status_code, req.text)
    return ret


def render_groovy_script(script_template, props):
    """
    Helper method for rendering groovy script with props

    :param script_template: groovy script template
    :param props: groovy script properties
    :returns: generated groovy script
    """
    template = Template(script_template)
    return template.safe_substitute(props)


def get_api_crumb(jenkins_url=None, jenkins_user=None, jenkins_password=None):
    """
    Obtains Jenkins API crumb, if CSRF protection is enabled.
    Jenkins params can be given by params or not, if not,
    params will be get from salt.

    :param jenkins_url: Jenkins URL (optional)
    :param jenkins_user: Jenkins admin username (optional)
    :param jenkins_password: Jenkins admin password (optional)
    :returns: salt-specified state dict
    """
    if not jenkins_url:
        jenkins_url, jenkins_user, jenkins_password = get_jenkins_auth()
    logger.debug("Obtaining Jenkins API crumb for URL: %s", jenkins_url)
    tokenReq = requests.get("%s/crumbIssuer/api/json" % jenkins_url,
                            auth=(jenkins_user, jenkins_password) if jenkins_user else None)
    if tokenReq.status_code == 200:
        logger.debug("Got Jenkins API crumb: %s", tokenReq.json())
        return tokenReq.json(), tokenReq.cookies
    elif tokenReq.status_code in [404, 401, 502, 503]:
        # 404 means CSRF security is disabled, so api crumb is not necessary,
        # 401 means unauthorized
        # 50x means jenkins is unavailabe - fail in call_groovy_script, but
        #     not here, to handle exception in state
        logger.debug("Got error %s: %s", str(tokenReq.status_code), tokenReq.reason)
        return None, None
    else:
        raise Exception("Cannot obtain Jenkins API crumb. Status code: %s. Text: %s" %
                        (tokenReq.status_code, tokenReq.text))


def get_jenkins_auth():
    """
    Get jenkins params from salt
    """
    jenkins_url = __salt__['config.get']('jenkins.url') or \
        __salt__['config.get']('jenkins:url') or \
        __salt__['pillar.get']('jenkins.url')

    jenkins_user = __salt__['config.get']('jenkins.user') or \
        __salt__['config.get']('jenkins:user') or \
        __salt__['pillar.get']('jenkins.user')

    jenkins_password = __salt__['config.get']('jenkins.password') or \
        __salt__['config.get']('jenkins:password') or \
        __salt__['pillar.get']('jenkins.password')

    return (jenkins_url, jenkins_user, jenkins_password)


def encode_password(password):
    """
    Hash plaintext password by jenkins bcrypt algorithm
    :param password: plain-text password
    :returns: bcrypt hashed password
    """
    if isinstance(password, str):
        return bcrypt.hashpw(password, bcrypt.gensalt(prefix=b"2a"))

def load_template(salt_url, env):
    """
       Return content of file `salt_url`
    """

    template_path = __salt__['cp.cache_file'](salt_url, env)
    with open(template_path, 'r') as template_file:
        template = template_file.read()

    return template

def api_call(name, template, success_msgs, params, display_name):
    test = __opts__['test']  # noqa
    ret = {
        'name': name,
        'changes': {},
        'result': False,
        'comment': '',
    }
    result = False
    if test:
        status = success_msgs[0]
        ret['changes'][name] = status
        ret['comment'] = '%s "%s" %s' % (display_name, name, status.lower())
    else:
        call_result = call_groovy_script(template, params)
        if call_result["code"] == 200 and call_result["msg"].strip() in success_msgs:
            status = call_result["msg"]
            if status == success_msgs[0]:
                ret['changes'][name] = status
            ret['comment'] = '%s "%s" %s' % (display_name, name, status.lower())
            result = True
        else:
            status = 'FAILED'
            logger.error(
                'Jenkins API call failure: %s', call_result["msg"])
            ret['comment'] = 'Jenkins API call failure: %s' % (call_result[
                "msg"])
    ret['result'] = None if test else result
    return ret

