#!/usr/bin/env python3
# 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)
