"""
Management of Portage package configuration on Gentoo
=====================================================

A state module to manage Portage configuration on Gentoo

.. code-block:: yaml

    salt:
        portage_config.flags:
            - use:
                - openssl
"""


def __virtual__():
    """
    Only load if the portage_config module is available in __salt__
    """
    if "portage_config.get_missing_flags" in __salt__:
        return "portage_config"
    return (False, "portage module could not be loaded")


def mod_init(low):
    """
    Enforce a nice structure on the configuration files.
    """
    try:
        __salt__["portage_config.enforce_nice_config"]()
    except Exception:  # pylint: disable=broad-except
        return False
    return True


def _flags_helper(conf, atom, new_flags, test=False):
    try:
        new_flags = __salt__["portage_config.get_missing_flags"](conf, atom, new_flags)
    except Exception:  # pylint: disable=broad-except
        import traceback

        return {"result": False, "comment": traceback.format_exc()}
    if new_flags:
        old_flags = __salt__["portage_config.get_flags_from_package_conf"](conf, atom)
        if not test:
            __salt__["portage_config.append_to_package_conf"](conf, atom, new_flags)
        return {"result": True, "changes": {"old": old_flags, "new": new_flags}}
    return {"result": None}


def _mask_helper(conf, atom, test=False):
    try:
        is_present = __salt__["portage_config.is_present"](conf, atom)
    except Exception:  # pylint: disable=broad-except
        import traceback

        return {"result": False, "comment": traceback.format_exc()}
    if not is_present:
        if not test:
            __salt__["portage_config.append_to_package_conf"](conf, string=atom)
        return {"result": True}
    return {"result": None}


def flags(
    name,
    use=None,
    accept_keywords=None,
    env=None,
    license=None,
    properties=None,
    unmask=False,
    mask=False,
):
    """
    Enforce the given flags on the given package or ``DEPEND`` atom.

    .. warning::

        In most cases, the affected package(s) need to be rebuilt in
        order to apply the changes.

    name
        The name of the package or its DEPEND atom
    use
        A list of ``USE`` flags
    accept_keywords
        A list of keywords to accept. ``~ARCH`` means current host arch, and will
        be translated into a line without keywords
    env
        A list of environment files
    license
        A list of accepted licenses
    properties
        A list of additional properties
    unmask
        A boolean to unmask the package
    mask
        A boolean to mask the package
    """
    ret = {"changes": {}, "comment": "", "name": name, "result": True}

    if use:
        result = _flags_helper("use", name, use, __opts__["test"])
        if result["result"]:
            ret["changes"]["use"] = result["changes"]
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if accept_keywords:
        result = _flags_helper(
            "accept_keywords", name, accept_keywords, __opts__["test"]
        )
        if result["result"]:
            ret["changes"]["accept_keywords"] = result["changes"]
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if env:
        result = _flags_helper("env", name, env, __opts__["test"])
        if result["result"]:
            ret["changes"]["env"] = result["changes"]
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if license:
        result = _flags_helper("license", name, license, __opts__["test"])
        if result["result"]:
            ret["changes"]["license"] = result["changes"]
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if properties:
        result = _flags_helper("properties", name, properties, __opts__["test"])
        if result["result"]:
            ret["changes"]["properties"] = result["changes"]
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if mask:
        result = _mask_helper("mask", name, __opts__["test"])
        if result["result"]:
            ret["changes"]["mask"] = "masked"
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if unmask:
        result = _mask_helper("unmask", name, __opts__["test"])
        if result["result"]:
            ret["changes"]["unmask"] = "unmasked"
        elif result["result"] is False:
            ret["result"] = False
            ret["comment"] = result["comment"]
            return ret

    if __opts__["test"] and not ret["result"]:
        ret["result"] = None

    return ret
