#!/usr/bin/env python3
#
# Copyright 2014 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Renders one or more template files using the Jinja template engine."""

import codecs
import argparse
import os
import sys

from util import build_utils
from util import resource_utils
import action_helpers  # build_utils adds //build to sys.path.
import zip_helpers

sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
from pylib.constants import host_paths

# Import jinja2 from third_party/jinja2
sys.path.append(os.path.join(host_paths.DIR_SOURCE_ROOT, 'third_party'))
import jinja2  # pylint: disable=F0401


class _RecordingFileSystemLoader(jinja2.FileSystemLoader):
  def __init__(self, searchpath):
    jinja2.FileSystemLoader.__init__(self, searchpath)
    self.loaded_templates = set()

  def get_source(self, environment, template):
    contents, filename, uptodate = jinja2.FileSystemLoader.get_source(
        self, environment, template)
    self.loaded_templates.add(os.path.relpath(filename))
    return contents, filename, uptodate


class JinjaProcessor:
  """Allows easy rendering of jinja templates with input file tracking."""
  def __init__(self, loader_base_dir, variables=None):
    self.loader_base_dir = loader_base_dir
    self.variables = variables or {}
    self.loader = _RecordingFileSystemLoader(loader_base_dir)
    self.env = jinja2.Environment(loader=self.loader)
    self.env.undefined = jinja2.StrictUndefined
    self.env.line_comment_prefix = '##'
    self.env.trim_blocks = True
    self.env.lstrip_blocks = True
    self._template_cache = {}  # Map of path -> Template

  def Render(self, input_filename, variables=None):
    input_rel_path = os.path.relpath(input_filename, self.loader_base_dir)
    template = self._template_cache.get(input_rel_path)
    if not template:
      template = self.env.get_template(input_rel_path)
      self._template_cache[input_rel_path] = template
    return template.render(variables or self.variables)

  def GetLoadedTemplates(self):
    return list(self.loader.loaded_templates)


def _ProcessFile(processor, input_filename, output_filename):
  output = processor.Render(input_filename)

  # If |output| is same with the file content, we skip update and
  # ninja's restat will avoid rebuilding things that depend on it.
  if os.path.isfile(output_filename):
    with codecs.open(output_filename, 'r', 'utf-8') as f:
      if f.read() == output:
        return

  with codecs.open(output_filename, 'w', 'utf-8') as output_file:
    output_file.write(output)


def _ProcessFiles(processor, input_filenames, inputs_base_dir, outputs_zip):
  with build_utils.TempDir() as temp_dir:
    path_info = resource_utils.ResourceInfoFile()
    for input_filename in input_filenames:
      relpath = os.path.relpath(os.path.abspath(input_filename),
                                os.path.abspath(inputs_base_dir))
      if relpath.startswith(os.pardir):
        raise Exception('input file %s is not contained in inputs base dir %s'
                        % (input_filename, inputs_base_dir))

      output_filename = os.path.join(temp_dir, relpath)
      parent_dir = os.path.dirname(output_filename)
      build_utils.MakeDirectory(parent_dir)
      _ProcessFile(processor, input_filename, output_filename)
      path_info.AddMapping(relpath, input_filename)

    path_info.Write(outputs_zip + '.info')
    with action_helpers.atomic_output(outputs_zip) as f:
      zip_helpers.zip_directory(f, temp_dir)


def _ParseVariables(variables_arg, error_func):
  variables = {}
  for v in action_helpers.parse_gn_list(variables_arg):
    if '=' not in v:
      error_func('--variables argument must contain "=": ' + v)
    name, _, value = v.partition('=')
    variables[name] = value
  return variables


def main():
  parser = argparse.ArgumentParser()
  parser.add_argument('--inputs', required=True,
                      help='GN-list of template files to process.')
  parser.add_argument('--includes', default='',
                      help="GN-list of files that get {% include %}'ed.")
  parser.add_argument('--output', help='The output file to generate. Valid '
                      'only if there is a single input.')
  parser.add_argument('--outputs-zip', help='A zip file for the processed '
                      'templates. Required if there are multiple inputs.')
  parser.add_argument('--inputs-base-dir', help='A common ancestor directory '
                      'of the inputs. Each output\'s path in the output zip '
                      'will match the relative path from INPUTS_BASE_DIR to '
                      'the input. Required if --output-zip is given.')
  parser.add_argument('--loader-base-dir', help='Base path used by the '
                      'template loader. Must be a common ancestor directory of '
                      'the inputs. Defaults to DIR_SOURCE_ROOT.',
                      default=host_paths.DIR_SOURCE_ROOT)
  parser.add_argument('--variables', help='Variables to be made available in '
                      'the template processing environment, as a GYP list '
                      '(e.g. --variables "channel=beta mstone=39")', default='')
  parser.add_argument('--check-includes', action='store_true',
                      help='Enable inputs and includes checks.')
  options = parser.parse_args()

  inputs = action_helpers.parse_gn_list(options.inputs)
  includes = action_helpers.parse_gn_list(options.includes)

  if (options.output is None) == (options.outputs_zip is None):
    parser.error('Exactly one of --output and --output-zip must be given')
  if options.output and len(inputs) != 1:
    parser.error('--output cannot be used with multiple inputs')
  if options.outputs_zip and not options.inputs_base_dir:
    parser.error('--inputs-base-dir must be given when --output-zip is used')

  variables = _ParseVariables(options.variables, parser.error)
  processor = JinjaProcessor(options.loader_base_dir, variables=variables)

  if options.output:
    _ProcessFile(processor, inputs[0], options.output)
  else:
    _ProcessFiles(processor, inputs, options.inputs_base_dir,
                  options.outputs_zip)

  if options.check_includes:
    all_inputs = set(processor.GetLoadedTemplates())
    all_inputs.difference_update(inputs)
    all_inputs.difference_update(includes)
    if all_inputs:
      raise Exception('Found files not listed via --includes:\n' +
                      '\n'.join(sorted(all_inputs)))


if __name__ == '__main__':
  main()
