#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.

"""
A Jinja template loader which allows for:

- dotted-notation package loading
- search-path-based overriding of same

Dotted notation
---------------

- Allow a Tool implementer to use a dotted-notation module name
  (as occuring in the ``PYTHONPATH``), then the given path within the
  module::

        @expose('jinja:<module.name>:<path/within/module.html>')

  e.g.::

        @expose('jinja:allura:templates/repo/file.html')

Overriding dotted notation
--------------------------

Allow a Tool implementer to override the theme baseline (or any
other Tool's) templates. This can be lighter-weight than subclassing
:class:`allura.plugin.ThemeProvider`, plus will allow for more fine-grained
changes.

This will also override ``extends`` and ``import`` Jinja tags.

This approach uses a:

- ``setup.py`` entry point to a class with...
- *magic* files and...
- (optionally) a class property to specify ordering

File Structure for Overriding dotted notation
=============================================

For the examples, assume the following directory structure::

    NewTool/
    |- setup.py                     <- entry point specified here
    |- newtool/
       |- app.py                    <- entry point target here
       |- templates/
       |  |- index.html             <- Tool's regular templates
       |- override                  <- override_root
          |- allura/                <- magic directory named after module
             |- templates/
                |- repo/
                   |- file.html     <- actual template

To override the above example, a Tool implementer would
add the following line to their Tool's ``setup.py`` (assuming usage in Allura,
with the default ``app_cfg``)::

    [allura.theme.override]
    newtool = newtool.app:NewToolApp

Then, in the neighbor path (see below) for the file containing the
Tool class, add the following path/file::

    override/allura/templates/repo/file.html

The template will be overridden. Note that after changing
``setup.py``, it would be required to re-initialize with setuptools::

    python setup.py develop

Specifying search path order with template_path_rules
=====================================================

If a highly specific ordering is required, such as if multiple Tools
are trying to override the same template, the entry point target
class can also contain a class property template_path_rules::

    class NewToolApp(Application):
        template_path_rules = [
            ['>', 'old-tool'],
        ]

Each rule specifies a postioner and an entry point or "signpost".
If no rule is provided, the default is ``['>', 'allura']``.

The "signposts" are:

- Any other app's override entry point name
- ``site-theme``
- ``allura`` (you probably shouldn't do this)
- ``project-theme`` **NOT IMPLEMENTED**
- ``tool-theme`` **NOT IMPLEMENTED**

The positioners are:

    >
        This overrider will be found BEFORE the specified entry point

    <
        This overrider will be found AFTER the specified entry point

    =
        This will replace one of the "signpost" entry points (if multiple apps
        try to do this for the same signpost, the result is undefined)

**TODO:** Support multiple partial themes

"""
import pkg_resources
import os
from collections import defaultdict

import jinja2
from ming.utils import LazyProperty

from allura.lib.helpers import topological_sort


class PackagePathLoader(jinja2.BaseLoader):
    def __init__(self, override_entrypoint='allura.theme.override',
                default_paths=None,
                override_root='override',
                ):
        '''
        Set up initial values... defaults are for Allura.
        '''
        # TODO: How does one handle project-theme?
        if default_paths is None:
            default_paths = [
                    #['project-theme', None],
                    ['site-theme', None],
                    ['allura', '/'],
                ]

        self.override_entrypoint = override_entrypoint
        self.default_paths = default_paths
        self.override_root = override_root

    @LazyProperty
    def fs_loader(self):
        return jinja2.FileSystemLoader(self.init_paths())

    def _load_paths(self):
        """
        Load all the paths to be processed, including defaults, in the default order.
        """
        paths = self.default_paths[:]  # copy default_paths
        paths[-1:0] = [  # insert all eps just before last item, by default
                [ep.name, pkg_resources.resource_filename(ep.module_name, "")]
                for ep in pkg_resources.iter_entry_points(self.override_entrypoint)
            ]
        return paths

    def _load_rules(self):
        """
        Load and pre-process the rules from the entry points.

        Rules are specified per-tool as a list of the form:

            template_path_rules = [
                    ['>', 'tool1'],  # this tool must be resolved before tool1
                    ['<', 'tool2'],  # this tool must be resolved after tool2
                    ['=', 'tool3'],  # this tool replaces all of tool3's templates
                ]

        Returns two lists of rules, order_rules and replacement_rules.

        order_rules represents all of the '>' and '<' rules and are returned
        as a list of pairs of the form ('a', 'b') indicating that path 'a' must
        come before path 'b'.

        replacement_rules represent all of the '=' rules and are returned as
        a dictionary mapping the paths to replace to the paths to replace with.
        """
        order_rules = []
        replacement_rules = {}
        for ep in pkg_resources.iter_entry_points(self.override_entrypoint):
            for rule in getattr(ep.load(), 'template_path_rules', []):
                if rule[0] == '>':
                    order_rules.append((ep.name, rule[1]))
                elif rule[0] == '=':
                    replacement_rules[rule[1]] = ep.name
                elif rule[0] == '<':
                    order_rules.append((rule[1], ep.name))
                else:
                    raise jinja2.TemplateError(
                        'Unknown template path rule in %s: %s' % (
                            ep.name, ' '.join(rule)))
        return order_rules, replacement_rules

    def _sort_paths(self, paths, rules):
        """
        Process all '>' and '<' rules, providing a partial ordering
        of the paths based on the given rules.

        The rules should already have been pre-processed by _load_rules
        to a list of partial ordering pairs ('a', 'b') indicating that
        path 'a' should come before path 'b'.
        """
        names = [p[0] for p in paths]
        # filter rules that reference non-existent paths to prevent "loops" in the graph
        rules = [r for r in rules if r[0] in names and r[1] in names]
        ordered_paths = topological_sort(names, rules)
        if ordered_paths is None:
            raise jinja2.TemplateError(
                'Loop detected in ordering of overrides')
        return paths.sort(key=lambda p: ordered_paths.index(p[0]))

    def _replace_signposts(self, paths, rules):
        """
        Process all '=' rules, replacing the rule target's path value with
        the rule's entry's path value.

        Multiple entries replacing the same signpost can cause indeterminate
        behavior, as the order of the entries is not entirely defined.
        However, if _sort_by_rules is called first, the partial ordering is
        respected.

        This mutates paths.
        """
        p_idx = lambda n: [e[0] for e in paths].index(n)
        for target, replacement in rules.items():
            try:
                removed = paths.pop(p_idx(replacement))
                paths[p_idx(target)][1] = removed[1]
            except ValueError:
                # target or replacement missing (may not be installed)
                pass

    def init_paths(self):
        '''
        Set up the setuptools entry point-based paths.
        '''
        paths = self._load_paths()
        order_rules, repl_rules = self._load_rules()

        self._sort_paths(paths, order_rules)
        self._replace_signposts(paths, repl_rules)

        return [p[1] for p in paths if p[1] is not None]

    def get_source(self, environment, template):
        '''
        Returns the source for jinja2 rendered templates. Can understand...
        - path/to/template.html
        - module:path/to/template.html
        '''
        src = None

        # look in all of the customized search locations...
        try:
            parts = [self.override_root] + template.split(':')
            if len(parts) > 2:
                parts[1:2] = parts[1].split('.')
            return self.fs_loader.get_source(environment, os.path.join(*parts))
        except jinja2.TemplateNotFound:
            # fall-back to attempt non-override loading
            pass

        if ':' in template:
            package, path = template.split(':', 2)
            filename = pkg_resources.resource_filename(package, path)
            return self.fs_loader.get_source(environment, filename)
        else:
            return self.fs_loader.get_source(environment, template)
