#!/usr/bin/python
# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

# Template loader and preprocessor.
#
# Preprocessor language:
#
#   //$ Comment line removed by preprocessor
#   $if VAR
#   $else
#   $endif
#
# VAR must be defined in the conditions dictionary.

import os


class TemplateLoader(object):
    """Loads template files from a path."""

    def __init__(self, root, subpaths, conditions={}):
        """Initializes loader.

    Args:
      root - a string, the directory under which the templates are stored.
      subpaths - a list of strings, subpaths of root in search order.
      conditions - a dictionay from strings to booleans.  Any conditional
        expression must be a key in the map.
    """
        self._root = root
        self._subpaths = subpaths
        self._conditions = conditions
        self._cache = {}

    def TryLoad(self, name, more_conditions={}):
        """Returns content of template file as a string, or None of not found."""
        conditions = dict(self._conditions, **more_conditions)
        cache_key = (name, tuple(sorted(conditions.items())))
        if cache_key in self._cache:
            return self._cache[cache_key]

        for subpath in self._subpaths:
            template_file = os.path.join(self._root, subpath, name)
            if os.path.exists(template_file):
                template = ''.join(open(template_file).readlines())
                template = self._Preprocess(template, template_file, conditions)
                self._cache[cache_key] = template
                return template

        return None

    def Load(self, name, more_conditions={}):
        """Returns contents of template file as a string, or raises an exception."""
        template = self.TryLoad(name, more_conditions)
        if template is not None:  # Can be empty string
            return template
        raise Exception("Could not find template '%s' on %s / %s" %
                        (name, self._root, self._subpaths))

    def _Preprocess(self, template, filename, conditions):

        def error(lineno, message):
            raise Exception('%s:%s: %s' % (filename, lineno, message))

        lines = template.splitlines(True)
        out = []

        condition_stack = []
        active = True
        seen_else = False

        for (lineno, full_line) in enumerate(lines):
            line = full_line.strip()

            if line.startswith('$'):
                words = line.split()
                directive = words[0]

                if directive == '$if':
                    if len(words) != 2:
                        error(lineno, '$if does not have single variable')
                    variable = words[1]
                    if variable in conditions:
                        condition_stack.append((active, seen_else))
                        active = active and conditions[variable]
                        seen_else = False
                    else:
                        error(lineno, "Unknown $if variable '%s'" % variable)

                elif directive == '$else':
                    if not condition_stack:
                        error(lineno, '$else without $if')
                    if seen_else:
                        raise error(lineno, 'Double $else')
                    seen_else = True
                    (parentactive,
                     _) = condition_stack[len(condition_stack) - 1]
                    active = not active and parentactive

                elif directive == '$endif':
                    if not condition_stack:
                        error(lineno, '$endif without $if')
                    (active, seen_else) = condition_stack.pop()

                else:
                    # Something else, like '$!MEMBERS'
                    if active:
                        out.append(full_line)
            elif line.startswith('//$'):
                pass  # Ignore pre-processor comment.

            else:
                if active:
                    out.append(full_line)
                continue

        if condition_stack:
            error(len(lines), 'Unterminated $if')

        return ''.join(out)
