# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
from __future__ import unicode_literals


def get_jenv():
    import frappe
    from frappe.utils.safe_exec import get_safe_globals

    if not getattr(frappe.local, 'jenv', None):
        from jinja2 import DebugUndefined
        from jinja2.sandbox import SandboxedEnvironment

        # frappe will be loaded last, so app templates will get precedence
        jenv = SandboxedEnvironment(
            loader=get_jloader(),
            undefined=DebugUndefined
        )
        set_filters(jenv)

        jenv.globals.update(get_safe_globals())
        jenv.globals.update(get_jenv_customization('methods'))
        jenv.globals.update({
            'resolve_class': resolve_class,
            'inspect': inspect,
            'web_blocks': web_blocks
        })

        frappe.local.jenv = jenv

    return frappe.local.jenv


def get_template(path):
    return get_jenv().get_template(path)


def get_email_from_template(name, args):
    from jinja2 import TemplateNotFound

    args = args or {}
    try:
        message = get_template('templates/emails/' + name + '.html').render(args)
    except TemplateNotFound as e:
        raise e

    try:
        text_content = get_template('templates/emails/' + name + '.txt').render(args)
    except TemplateNotFound:
        text_content = None

    return (message, text_content)


def validate_template(html):
    """Throws exception if there is a syntax error in the Jinja Template"""
    import frappe
    from jinja2 import TemplateSyntaxError

    jenv = get_jenv()
    try:
        jenv.from_string(html)
    except TemplateSyntaxError as e:
        frappe.msgprint('Line {}: {}'.format(e.lineno, e.message))
        frappe.throw(frappe._("Syntax error in template"))


def render_template(template, context, is_path=None, safe_render=True):
    '''Render a template using Jinja

	:param template: path or HTML containing the jinja template
	:param context: dict of properties to pass to the template
	:param is_path: (optional) assert that the `template` parameter is a path
	:param safe_render: (optional) prevent server side scripting via jinja templating
	'''

    from frappe import get_traceback, throw
    from jinja2 import TemplateError

    if not template:
        return ""

    if is_path or guess_is_path(template):
        return get_jenv().get_template(template).render(context)
    else:
        if safe_render and ".__" in template:
            throw("Illegal template")
        try:
            return get_jenv().from_string(template).render(context)
        except TemplateError:
            throw(title="Jinja Template Error",
                  msg="<pre>{template}</pre><pre>{tb}</pre>".format(template=template, tb=get_traceback()))


def guess_is_path(template):
    # template can be passed as a path or content
    # if its single line and ends with a html, then its probably a path
    if not '\n' in template and '.' in template:
        extn = template.rsplit('.')[-1]
        if extn in ('html', 'css', 'scss', 'py', 'md', 'json', 'js', 'xml'):
            return True

    return False


def get_jloader():
    import frappe
    if not getattr(frappe.local, 'jloader', None):
        from jinja2 import ChoiceLoader, PackageLoader, PrefixLoader

        if frappe.local.flags.in_setup_help:
            apps = ['frappe']
        else:
            apps = frappe.get_hooks('template_apps')
            if not apps:
                apps = frappe.local.flags.web_pages_apps or frappe.get_installed_apps(sort=True)
                apps.reverse()

        if not "frappe" in apps:
            apps.append('frappe')

        frappe.local.jloader = ChoiceLoader(
            # search for something like app/templates/...
            [PrefixLoader(dict(
                (app, PackageLoader(app, ".")) for app in apps
            ))]

            # search for something like templates/...
            + [PackageLoader(app, ".") for app in apps]
        )

    return frappe.local.jloader


def set_filters(jenv):
    import frappe
    from frappe.utils import global_date_format, cint, cstr, flt, markdown
    from frappe.website.utils import get_shade, abs_url

    jenv.filters["global_date_format"] = global_date_format
    jenv.filters["markdown"] = markdown
    jenv.filters["json"] = frappe.as_json
    jenv.filters["get_shade"] = get_shade
    jenv.filters["len"] = len
    jenv.filters["int"] = cint
    jenv.filters["str"] = cstr
    jenv.filters["flt"] = flt
    jenv.filters["abs_url"] = abs_url

    if frappe.flags.in_setup_help:
        return

    jenv.filters.update(get_jenv_customization('filters'))


def get_jenv_customization(customization_type):
    '''Returns a dict with filter/method name as key and definition as value'''

    import frappe

    out = {}
    if not getattr(frappe.local, "site", None):
        return out

    values = frappe.get_hooks("jenv", {}).get(customization_type)
    if not values:
        return out

    for value in values:
        fn_name, fn_string = value.split(":")
        out[fn_name] = frappe.get_attr(fn_string)

    return out


def resolve_class(classes):
    import frappe

    if classes is None:
        return ''

    if isinstance(classes, frappe.string_types):
        return classes

    if isinstance(classes, (list, tuple)):
        return ' '.join([resolve_class(c) for c in classes]).strip()

    if isinstance(classes, dict):
        return ' '.join([classname for classname in classes if classes[classname]]).strip()

    return classes


def inspect(var, render=True):
    context = {"var": var}
    if render:
        html = "<pre>{{ var | pprint | e }}</pre>"
    else:
        html = ""
    return get_jenv().from_string(html).render(context)


def web_blocks(blocks):
    from frappe import get_doc
    from frappe.website.doctype.web_page.web_page import get_web_blocks_html

    web_blocks = []
    for block in blocks:
        doc = {
            'doctype': 'Web Page Block',
            'web_template': block['template'],
            'web_template_values': block['values'],
            'add_top_padding': 1,
            'add_bottom_padding': 1,
            'add_container': 1,
            'hide_block': 0,
            'css_class': ''
        }
        doc.update(block)
        web_blocks.append(get_doc(doc))

    out = get_web_blocks_html(web_blocks)

    html = out.html
    for script in out.scripts:
        html += '<script>{}</script>'.format(script)

    return html

@@ -2971,16 +2971,16 @@
  if 
-not 
 '%5Cn'
+ not
  in 
@@ -3639,20 +3639,16 @@
  if 
-not 
 %22frappe%22
  in 
@@ -3643,16 +3643,20 @@
 %22frappe%22
+ not
  in apps

change construction for not in