#!/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 dictionary 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)
