# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import copy
from datetime import datetime
from functools import partial
import os
import re

from code import Code
import json_parse

# The template for the header file of the generated FeatureProvider.
HEADER_FILE_TEMPLATE = """
// Copyright %(year)s The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// GENERATED FROM THE FEATURES FILE:
//   %(source_files)s
// DO NOT EDIT.

#ifndef %(header_guard)s
#define %(header_guard)s

namespace extensions {
class FeatureProvider;

void %(method_name)s(FeatureProvider* provider);

}  // namespace extensions

#endif  // %(header_guard)s
"""

# The beginning of the .cc file for the generated FeatureProvider.
CC_FILE_BEGIN = """
// Copyright %(year)s The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// GENERATED FROM THE FEATURES FILE:
//   %(source_files)s
// DO NOT EDIT.

#include "%(header_file_path)s"

#include "extensions/common/features/complex_feature.h"
#include "extensions/common/features/feature_provider.h"
#include "extensions/common/features/manifest_feature.h"
#include "extensions/common/features/permission_feature.h"

namespace extensions {

void %(method_name)s(FeatureProvider* provider) {
"""

# The end of the .cc file for the generated FeatureProvider.
CC_FILE_END = """
}

}  // namespace extensions
"""

# Returns true if the list 'l' does not contain any strings that look like
# extension ids.
def ListDoesNotContainPlainExtensionIds(l):
  # For now, let's just say anything 32 characters in length is an id.
  return len(filter(lambda s: len(s) == 32, l)) == 0

# A "grammar" for what is and isn't allowed in the features.json files. This
# grammar has to list all possible keys and the requirements for each. The
# format of each entry is:
#   'key': {
#     allowed_type_1: optional_properties,
#     allowed_type_2: optional_properties,
#   }
# |allowed_types| are the types of values that can be used for a given key. The
# possible values are list, unicode, bool, and int.
# |optional_properties| provide more restrictions on the given type. The options
# are:
#   'subtype': Only applicable for lists. If provided, this enforces that each
#              entry in the list is of the specified type.
#   'enum_map': A map of strings to C++ enums. When the compiler sees the given
#               enum string, it will replace it with the C++ version in the
#               compiled code. For instance, if a feature specifies
#               'channel': 'stable', the generated C++ will assign
#               version_info::Channel::STABLE to channel. The keys in this map
#               also serve as a list all of possible values.
#   'allow_all': Only applicable for lists. If present, this will check for
#                a value of "all" for a list value, and will replace it with
#                the collection of all possible values. For instance, if a
#                feature specifies 'contexts': 'all', the generated C++ will
#                assign the list of Feature::BLESSED_EXTENSION_CONTEXT,
#                Feature::BLESSED_WEB_PAGE_CONTEXT et al for contexts. If not
#                specified, defaults to false.
#   'validators': A list of (function, str) pairs with a function to run on the
#                 value for a feature. Validators allow for more flexible or
#                 one-off style validation than just what's in the grammar (such
#                 as validating the content of a string). The validator function
#                 should return True if the value is valid, and False otherwise.
#                 If the value is invalid, the specified error will be added for
#                 that key.
#   'values': A list of all possible allowed values for a given key.
#   'shared': Boolean that, if set, ensures that only one of the associated
#       features has the feature property set. Used primarily for complex
#       features - for simple features, there is always at most one feature
#       setting an option.
# If a type definition does not have any restrictions (beyond the type itself),
# an empty definition ({}) is used.
FEATURE_GRAMMAR = (
  {
    'alias': {
      unicode: {},
      'shared': True
    },
    'blacklist': {
      list: {
        'subtype': unicode,
        'validators': [
          (ListDoesNotContainPlainExtensionIds,
           'list should only have hex-encoded SHA1 hashes of extension ids')
        ]
      }
    },
    'channel': {
      unicode: {
        'enum_map': {
          'trunk': 'version_info::Channel::UNKNOWN',
          'canary': 'version_info::Channel::CANARY',
          'dev': 'version_info::Channel::DEV',
          'beta': 'version_info::Channel::BETA',
          'stable': 'version_info::Channel::STABLE',
        }
      }
    },
    'command_line_switch': {
      unicode: {}
    },
    'component_extensions_auto_granted': {
      bool: {}
    },
    'contexts': {
      list: {
        'enum_map': {
          'blessed_extension': 'Feature::BLESSED_EXTENSION_CONTEXT',
          'blessed_web_page': 'Feature::BLESSED_WEB_PAGE_CONTEXT',
          'content_script': 'Feature::CONTENT_SCRIPT_CONTEXT',
          'extension_service_worker': 'Feature::SERVICE_WORKER_CONTEXT',
          'lock_screen_extension': 'Feature::LOCK_SCREEN_EXTENSION_CONTEXT',
          'web_page': 'Feature::WEB_PAGE_CONTEXT',
          'webui': 'Feature::WEBUI_CONTEXT',
          'unblessed_extension': 'Feature::UNBLESSED_EXTENSION_CONTEXT',
        },
        'allow_all': True
      },
    },
    'default_parent': {
      bool: {'values': [True]}
    },
    'dependencies': {
      list: {'subtype': unicode}
    },
    'extension_types': {
      list: {
        'enum_map': {
          'extension': 'Manifest::TYPE_EXTENSION',
          'hosted_app': 'Manifest::TYPE_HOSTED_APP',
          'legacy_packaged_app': 'Manifest::TYPE_LEGACY_PACKAGED_APP',
          'platform_app': 'Manifest::TYPE_PLATFORM_APP',
          'shared_module': 'Manifest::TYPE_SHARED_MODULE',
          'theme': 'Manifest::TYPE_THEME',
        },
        'allow_all': True
      },
    },
    'location': {
      unicode: {
        'enum_map': {
          'component': 'SimpleFeature::COMPONENT_LOCATION',
          'external_component': 'SimpleFeature::EXTERNAL_COMPONENT_LOCATION',
          'policy': 'SimpleFeature::POLICY_LOCATION',
        }
      }
    },
    'internal': {
      bool: {'values': [True]}
    },
    'matches': {
      list: {'subtype': unicode}
    },
    'max_manifest_version': {
      int: {'values': [1, 2]}
    },
    'min_manifest_version': {
      int: {'values': [2, 3]}
    },
    'noparent': {
      bool: {'values': [True]}
    },
    'platforms': {
      list: {
        'enum_map': {
          'chromeos': 'Feature::CHROMEOS_PLATFORM',
          'linux': 'Feature::LINUX_PLATFORM',
          'mac': 'Feature::MACOSX_PLATFORM',
          'win': 'Feature::WIN_PLATFORM',
        }
      }
    },
    'session_types': {
      list: {
        'enum_map': {
          'regular': 'FeatureSessionType::REGULAR',
          'kiosk': 'FeatureSessionType::KIOSK',
          'kiosk.autolaunched': 'FeatureSessionType::AUTOLAUNCHED_KIOSK',
        }
      }
    },
    'source': {
      unicode: {},
      'shared': True
    },
    'whitelist': {
      list: {
        'subtype': unicode,
        'validators': [
          (ListDoesNotContainPlainExtensionIds,
           'list should only have hex-encoded SHA1 hashes of extension ids')
        ]
      }
    },
  })

FEATURE_TYPES = ['APIFeature', 'BehaviorFeature',
                 'ManifestFeature', 'PermissionFeature']

def HasProperty(property_name, value):
  return property_name in value

def HasAtLeastOneProperty(property_names, value):
  return any([HasProperty(name, value) for name in property_names])

def DoesNotHaveAllProperties(property_names, value):
  return not all([HasProperty(name, value) for name in property_names])

def DoesNotHaveProperty(property_name, value):
  return property_name not in value

def IsFeatureCrossReference(property_name, reverse_property_name, feature,
                            all_features):
  """ Verifies that |property_name| on |feature| references a feature that
  references |feature| back using |reverse_property_name| property.
  |property_name| and |reverse_property_name| are expected to have string
  values.
  """
  value = feature.GetValue(property_name)
  if not value:
    return True
  # String property values will be wrapped in "", strip those.
  value_regex = re.compile('^"(.+)"$')
  parsed_value = value_regex.match(value)
  assert parsed_value, (
      'IsFeatureCrossReference should only be used on unicode properties')

  referenced_feature = all_features.get(parsed_value.group(1))
  if not referenced_feature:
    return False
  reverse_reference_value = referenced_feature.GetValue(reverse_property_name)
  if not reverse_reference_value:
    return False
  # Don't validate reverse reference value for child features - chances are that
  # the value was inherited from a feature parent, in which case it won't match
  # current feature name.
  if feature.has_parent:
    return True
  return reverse_reference_value == ('"%s"' % feature.name)

SIMPLE_FEATURE_CPP_CLASSES = ({
  'APIFeature': 'SimpleFeature',
  'ManifestFeature': 'ManifestFeature',
  'PermissionFeature': 'PermissionFeature',
  'BehaviorFeature': 'SimpleFeature',
})

VALIDATION = ({
  'all': [
    (partial(HasAtLeastOneProperty, ['channel', 'dependencies']),
     'Features must specify either a channel or dependencies'),
  ],
  'APIFeature': [
    (partial(HasProperty, 'contexts'),
     'APIFeatures must specify at least one context'),
    (partial(DoesNotHaveAllProperties, ['alias', 'source']),
     'Features cannot specify both alias and source.')
  ],
  'ManifestFeature': [
    (partial(HasProperty, 'extension_types'),
     'ManifestFeatures must specify at least one extension type'),
    (partial(DoesNotHaveProperty, 'contexts'),
     'ManifestFeatures do not support contexts.'),
    (partial(DoesNotHaveProperty, 'alias'),
     'ManifestFeatures do not support alias.'),
    (partial(DoesNotHaveProperty, 'source'),
     'ManifestFeatures do not support source.'),
  ],
  'BehaviorFeature': [
    (partial(DoesNotHaveProperty, 'alias'),
     'BehaviorFeatures do not support alias.'),
    (partial(DoesNotHaveProperty, 'source'),
     'BehaviorFeatures do not support source.'),
   ],
  'PermissionFeature': [
    (partial(HasProperty, 'extension_types'),
     'PermissionFeatures must specify at least one extension type'),
    (partial(DoesNotHaveProperty, 'contexts'),
     'PermissionFeatures do not support contexts.'),
    (partial(DoesNotHaveProperty, 'alias'),
     'PermissionFeatures do not support alias.'),
    (partial(DoesNotHaveProperty, 'source'),
     'PermissionFeatures do not support source.'),
  ],
})

FINAL_VALIDATION = ({
  'all': [],
  'APIFeature': [
    (partial(IsFeatureCrossReference, 'alias', 'source'),
     'A feature alias property should reference a feature whose source '
     'property references it back.'),
    (partial(IsFeatureCrossReference, 'source', 'alias'),
     'A feature source property should reference a feature whose alias '
     'property references it back.')

  ],
  'ManifestFeature': [],
  'BehaviorFeature': [],
  'PermissionFeature': []
})

# These keys are used to find the parents of different features, but are not
# compiled into the features themselves.
IGNORED_KEYS = ['default_parent']

# By default, if an error is encountered, assert to stop the compilation. This
# can be disabled for testing.
ENABLE_ASSERTIONS = True

# JSON parsing returns all strings of characters as unicode types. For testing,
# we can enable converting all string types to unicode to avoid writing u''
# everywhere.
STRINGS_TO_UNICODE = False

def GetCodeForFeatureValues(feature_values):
  """ Gets the Code object for setting feature values for this object. """
  c = Code()
  for key in sorted(feature_values.keys()):
    if key in IGNORED_KEYS:
      continue;

    # TODO(devlin): Remove this hack as part of 842387.
    set_key = key
    if key == "whitelist":
      set_key = "allowlist"
    elif key == "blacklist":
      set_key = "blocklist"

    c.Append('feature->set_%s(%s);' % (set_key, feature_values[key]))
  return c

class Feature(object):
  """A representation of a single simple feature that can handle all parsing,
  validation, and code generation.
  """
  def __init__(self, name):
    self.name = name
    self.has_parent = False
    self.errors = []
    self.feature_values = {}
    self.shared_values = {}

  def _GetType(self, value):
    """Returns the type of the given value. This can be different than type() if
    STRINGS_TO_UNICODE is enabled.
    """
    t = type(value)
    if not STRINGS_TO_UNICODE:
      return t
    if t is str:
      return unicode
    return t

  def AddError(self, error):
    """Adds an error to the feature. If ENABLE_ASSERTIONS is active, this will
    also assert to stop the compilation process (since errors should never be
    found in production).
    """
    self.errors.append(error)
    if ENABLE_ASSERTIONS:
      assert False, error

  def _AddKeyError(self, key, error):
    """Adds an error relating to a particular key in the feature.
    """
    self.AddError('Error parsing feature "%s" at key "%s": %s' %
                      (self.name, key, error))

  def _GetCheckedValue(self, key, expected_type, expected_values,
                       enum_map, value):
    """Returns a string to be used in the generated C++ code for a given key's
    python value, or None if the value is invalid. For example, if the python
    value is True, this returns 'true', for a string foo, this returns "foo",
    and for an enum, this looks up the C++ definition in the enum map.
      key: The key being parsed.
      expected_type: The expected type for this value, or None if any type is
                     allowed.
      expected_values: The list of allowed values for this value, or None if any
                       value is allowed.
      enum_map: The map from python value -> cpp value for all allowed values,
               or None if no special mapping should be made.
      value: The value to check.
    """
    valid = True
    if expected_values and value not in expected_values:
      self._AddKeyError(key, 'Illegal value: "%s"' % value)
      valid = False

    t = self._GetType(value)
    if expected_type and t is not expected_type:
      self._AddKeyError(key, 'Illegal value: "%s"' % value)
      valid = False

    if not valid:
      return None

    if enum_map:
      return enum_map[value]

    if t in [str, unicode]:
      return '"%s"' % str(value)
    if t is int:
      return str(value)
    if t is bool:
      return 'true' if value else 'false'
    assert False, 'Unsupported type: %s' % value

  def _ParseKey(self, key, value, shared_values, grammar):
    """Parses the specific key according to the grammar rule for that key if it
    is present in the json value.
      key: The key to parse.
      value: The full value for this feature.
      shared_values: Set of shared vfalues associated with this feature.
      grammar: The rule for the specific key.
    """
    if key not in value:
      return
    v = value[key]

    is_all = False
    if v == 'all' and list in grammar and 'allow_all' in grammar[list]:
      v = []
      is_all = True

    if 'shared' in grammar and key in shared_values:
      self._AddKeyError(key, 'Key can be set at most once per feature.')
      return

    value_type = self._GetType(v)
    if value_type not in grammar:
      self._AddKeyError(key, 'Illegal value: "%s"' % v)
      return

    expected = grammar[value_type]
    expected_values = None
    enum_map = None
    if 'values' in expected:
      expected_values = expected['values']
    elif 'enum_map' in expected:
      enum_map = expected['enum_map']
      expected_values = enum_map.keys()

    if is_all:
      v = copy.deepcopy(expected_values)

    expected_type = None
    if value_type is list and 'subtype' in expected:
      expected_type = expected['subtype']

    cpp_value = None
    # If this value is a list, iterate over each entry and validate. Otherwise,
    # validate the single value.
    if value_type is list:
      cpp_value = []
      for sub_value in v:
        cpp_sub_value = self._GetCheckedValue(key, expected_type,
                                              expected_values, enum_map,
                                              sub_value)
        if cpp_sub_value:
          cpp_value.append(cpp_sub_value)
      if cpp_value:
        cpp_value = '{' + ','.join(cpp_value) + '}'
    else:
      cpp_value = self._GetCheckedValue(key, expected_type, expected_values,
                                        enum_map, v)

    if 'validators' in expected:
      validators = expected['validators']
      for validator, error in validators:
        if not validator(v):
          self._AddKeyError(key, error)

    if cpp_value:
      if 'shared' in grammar:
        shared_values[key] = cpp_value
      else:
        self.feature_values[key] = cpp_value
    elif key in self.feature_values:
      # If the key is empty and this feature inherited a value from its parent,
      # remove the inherited value.
      del self.feature_values[key]

  def SetParent(self, parent):
    """Sets the parent of this feature, and inherits all properties from that
    parent.
    """
    assert not self.feature_values, 'Parents must be set before parsing'
    self.feature_values = copy.deepcopy(parent.feature_values)
    self.has_parent = True

  def SetSharedValues(self, values):
    self.shared_values = values

  def Parse(self, parsed_json, shared_values):
    """Parses the feature from the given json value."""
    for key in parsed_json.keys():
      if key not in FEATURE_GRAMMAR:
        self._AddKeyError(key, 'Unrecognized key')
    for key, key_grammar in FEATURE_GRAMMAR.iteritems():
      self._ParseKey(key, parsed_json, shared_values, key_grammar)

  def Validate(self, feature_type, shared_values):
    feature_values = self.feature_values.copy()
    feature_values.update(shared_values)
    for validator, error in (VALIDATION[feature_type] + VALIDATION['all']):
      if not validator(feature_values):
        self.AddError(error)

  def GetCode(self, feature_type):
    """Returns the Code object for generating this feature."""
    c = Code()
    cpp_feature_class = SIMPLE_FEATURE_CPP_CLASSES[feature_type]
    c.Append('%s* feature = new %s();' % (cpp_feature_class, cpp_feature_class))
    c.Append('feature->set_name("%s");' % self.name)
    c.Concat(GetCodeForFeatureValues(self.GetAllFeatureValues()))
    return c

  def AsParent(self):
    """ Returns the feature values that should be inherited by children features
    when this feature is set as parent.
    """
    return self

  def GetValue(self, key):
    """ Gets feature value for the specified key """
    value = self.feature_values.get(key)
    return value if value else self.shared_values.get(key)

  def GetAllFeatureValues(self):
    """ Gets all values set for this feature. """
    values = self.feature_values.copy()
    values.update(self.shared_values)
    return values

  def GetErrors(self):
    return self.errors;

class ComplexFeature(Feature):
  """ Complex feature - feature that is comprised of list of features.
  Overall complex feature is available if any of contained
  feature is available.
  """
  def __init__(self, name):
    Feature.__init__(self, name)
    self.feature_list = []

  def GetCode(self, feature_type):
    c = Code()
    c.Append('std::vector<Feature*> features;')
    for f in self.feature_list:
      # Sanity check that components of complex features have no shared values
      # set.
      assert not f.shared_values
      c.Sblock('{')
      c.Concat(f.GetCode(feature_type))
      c.Append('features.push_back(feature);')
      c.Eblock('}')
    c.Append('ComplexFeature* feature(new ComplexFeature(&features));')
    c.Append('feature->set_name("%s");' % self.name)
    c.Concat(GetCodeForFeatureValues(self.shared_values))
    return c

  def AsParent(self):
    parent = None
    for p in self.feature_list:
      if 'default_parent' in p.feature_values:
        parent = p
        break
    assert parent, 'No default parent found for %s' % self.name
    return parent

  def GetErrors(self):
    errors = copy.copy(self.errors)
    for feature in self.feature_list:
      errors.extend(feature.GetErrors())
    return errors

class FeatureCompiler(object):
  """A compiler to load, parse, and generate C++ code for a number of
  features.json files."""
  def __init__(self, chrome_root, source_files, feature_type,
               method_name, out_root, out_base_filename):
    # See __main__'s ArgumentParser for documentation on these properties.
    self._chrome_root = chrome_root
    self._source_files = source_files
    self._feature_type = feature_type
    self._method_name = method_name
    self._out_root = out_root
    self._out_base_filename = out_base_filename

    # The json value for the feature files.
    self._json = {}
    # The parsed features.
    self._features = {}

  def Load(self):
    """Loads and parses the source from each input file and puts the result in
    self._json."""
    for f in self._source_files:
      abs_source_file = os.path.join(self._chrome_root, f)
      try:
        with open(abs_source_file, 'r') as f:
          f_json = json_parse.Parse(f.read())
      except:
        print('FAILED: Exception encountered while loading "%s"' %
                  abs_source_file)
        raise
      dupes = set(f_json) & set(self._json)
      assert not dupes, 'Duplicate keys found: %s' % list(dupes)
      self._json.update(f_json)

  def _FindParent(self, feature_name, feature_value):
    """Checks to see if a feature has a parent. If it does, returns the
    parent."""
    no_parent = False
    if type(feature_value) is list:
      no_parent_values = ['noparent' in v for v in feature_value]
      no_parent = all(no_parent_values)
      assert no_parent or not any(no_parent_values), (
              '"%s:" All child features must contain the same noparent value' %
                  feature_name)
    else:
      no_parent = 'noparent' in feature_value
    sep = feature_name.rfind('.')
    if sep is -1 or no_parent:
      return None

    parent_name = feature_name[:sep]
    while sep != -1 and parent_name not in self._features:
      # This recursion allows for a feature to have a parent that isn't a direct
      # ancestor. For instance, we could have feature 'alpha', and feature
      # 'alpha.child.child', where 'alpha.child.child' inherits from 'alpha'.
      # TODO(devlin): Is this useful? Or logical?
      sep = feature_name.rfind('.', 0, sep)
      parent_name = feature_name[:sep]

    if sep == -1:
      # TODO(devlin): It'd be kind of nice to be able to assert that the
      # deduced parent name is in our features, but some dotted features don't
      # have parents and also don't have noparent, e.g. system.cpu. We should
      # probably just noparent them so that we can assert this.
      #   raise KeyError('Could not find parent "%s" for feature "%s".' %
      #                      (parent_name, feature_name))
      return None
    return self._features[parent_name].AsParent()

  def _CompileFeature(self, feature_name, feature_value):
    """Parses a single feature."""
    if 'nocompile' in feature_value:
      assert feature_value['nocompile'], (
          'nocompile should only be true; otherwise omit this key.')
      return

    def parse_and_validate(name, value, parent, shared_values):
      try:
        feature = Feature(name)
        if parent:
          feature.SetParent(parent)
        feature.Parse(value, shared_values)
        feature.Validate(self._feature_type, shared_values)
        return feature
      except:
        print('Failure to parse feature "%s"' % feature_name)
        raise

    parent = self._FindParent(feature_name, feature_value)
    shared_values = {}

    # Handle complex features, which are lists of simple features.
    if type(feature_value) is list:
      feature = ComplexFeature(feature_name)

      # This doesn't handle nested complex features. I think that's probably for
      # the best.
      for v in feature_value:
        feature.feature_list.append(
            parse_and_validate(feature_name, v, parent, shared_values))
      self._features[feature_name] = feature
    else:
      self._features[feature_name] = parse_and_validate(
          feature_name, feature_value, parent, shared_values)

    # Apply parent shared values at the end to enable child features to
    # override parent shared value - if parent shared values are added to
    # shared value set before a child feature is parsed, the child feature
    # overriding shared values set by its parent would cause an error due to
    # shared values being set twice.
    final_shared_values = copy.deepcopy(parent.shared_values) if parent else {}
    final_shared_values.update(shared_values)
    self._features[feature_name].SetSharedValues(final_shared_values)

  def _FinalValidation(self):
    validators = FINAL_VALIDATION['all'] + FINAL_VALIDATION[self._feature_type]
    for name, feature in self._features.items():
      for validator, error in validators:
        if not validator(feature, self._features):
          feature.AddError(error)

  def Compile(self):
    """Parses all features after loading the input files."""
    # Iterate over in sorted order so that parents come first.
    for k in sorted(self._json.keys()):
      self._CompileFeature(k, self._json[k])
    self._FinalValidation()

  def Render(self):
    """Returns the Code object for the body of the .cc file, which handles the
    initialization of all features."""
    c = Code()
    c.Sblock()
    for k in sorted(self._features.keys()):
      c.Sblock('{')
      feature = self._features[k]
      c.Concat(feature.GetCode(self._feature_type))
      c.Append('provider->AddFeature("%s", feature);' % k)
      c.Eblock('}')
    c.Eblock()
    return c

  def Write(self):
    """Writes the output."""
    header_file = self._out_base_filename + '.h'
    cc_file = self._out_base_filename + '.cc'

    include_file_root = self._out_root
    GEN_DIR_PREFIX = 'gen/'
    if include_file_root.startswith(GEN_DIR_PREFIX):
      include_file_root = include_file_root[len(GEN_DIR_PREFIX):]
    header_file_path = '%s/%s' % (include_file_root, header_file)
    cc_file_path = '%s/%s' % (include_file_root, cc_file)
    substitutions = ({
        'header_file_path': header_file_path,
        'header_guard': (header_file_path.replace('/', '_').
                             replace('.', '_').upper()),
        'method_name': self._method_name,
        'source_files': str(self._source_files),
        'year': str(datetime.now().year)
    })
    if not os.path.exists(self._out_root):
      os.makedirs(self._out_root)
    # Write the .h file.
    with open(os.path.join(self._out_root, header_file), 'w') as f:
      header_file = Code()
      header_file.Append(HEADER_FILE_TEMPLATE)
      header_file.Substitute(substitutions)
      f.write(header_file.Render().strip())
    # Write the .cc file.
    with open(os.path.join(self._out_root, cc_file), 'w') as f:
      cc_file = Code()
      cc_file.Append(CC_FILE_BEGIN)
      cc_file.Substitute(substitutions)
      cc_file.Concat(self.Render())
      cc_end = Code()
      cc_end.Append(CC_FILE_END)
      cc_end.Substitute(substitutions)
      cc_file.Concat(cc_end)
      f.write(cc_file.Render().strip())

if __name__ == '__main__':
  parser = argparse.ArgumentParser(description='Compile json feature files')
  parser.add_argument('chrome_root', type=str,
                      help='The root directory of the chrome checkout')
  parser.add_argument(
      'feature_type', type=str,
      help='The name of the class to use in feature generation ' +
               '(e.g. APIFeature, PermissionFeature)')
  parser.add_argument('method_name', type=str,
                      help='The name of the method to populate the provider')
  parser.add_argument('out_root', type=str,
                      help='The root directory to generate the C++ files into')
  parser.add_argument(
      'out_base_filename', type=str,
      help='The base filename for the C++ files (.h and .cc will be appended)')
  parser.add_argument('source_files', type=str, nargs='+',
                      help='The source features.json files')
  args = parser.parse_args()
  if args.feature_type not in FEATURE_TYPES:
    raise NameError('Unknown feature type: %s' % args.feature_type)
  c = FeatureCompiler(args.chrome_root, args.source_files, args.feature_type,
                      args.method_name, args.out_root,
                      args.out_base_filename)
  c.Load()
  c.Compile()
  c.Write()
