#!/usr/bin/env python
# Copyright (c) 2012 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.


class TemplateWriter(object):
  '''Abstract base class for writing policy templates in various formats.
  The methods of this class will be called by PolicyTemplateGenerator.
  '''

  def __init__(self, platforms, config):
    '''Initializes a TemplateWriter object.

    Args:
      platforms: List of platforms for which this writer can write policies.
      config: A dictionary of information required to generate the template.
        It contains some key-value pairs, including the following examples:
          'build': 'chrome' or 'chromium'
          'branding': 'Google Chrome' or 'Chromium'
          'mac_bundle_id': The Mac bundle id of Chrome. (Only set when building
            for Mac.)
      messages: List of all the message strings from the grd file. Most of them
        are also present in the policy data structures that are passed to
        methods. That is the preferred way of accessing them, this should only
        be used in exceptional cases. An example for its use is the
        IDS_POLICY_WIN_SUPPORTED_WINXPSP2 message in ADM files, because that
        cannot be associated with any policy or group.
    '''
    self.platforms = platforms
    self.config = config

  def IsDeprecatedPolicySupported(self, policy):
    '''Checks if the given deprecated policy is supported by the writer.

    Args:
      policy: The dictionary of the policy.

    Returns:
      True if the writer chooses to include the deprecated 'policy' in its
      output.
    '''
    return False

  def IsFuturePolicySupported(self, policy):
    '''Checks if the given future policy is supported by the writer.

    Args:
      policy: The dictionary of the policy.

    Returns:
      True if the writer chooses to include the deprecated 'policy' in its
      output.
    '''
    return False

  def IsPolicySupported(self, policy):
    '''Checks if the given policy is supported by the writer.
    In other words, the set of platforms supported by the writer
    has a common subset with the set of platforms that support
    the policy.

    Args:
      policy: The dictionary of the policy.

    Returns:
      True if the writer chooses to include 'policy' in its output.
    '''
    if ('deprecated' in policy and policy['deprecated'] is True and
        not self.IsDeprecatedPolicySupported(policy)):
      return False

    if ('future' in policy and policy['future'] is True and
        not self.IsFuturePolicySupported(policy)):
      return False

    if '*' in self.platforms:
      # Currently chrome_os is only catched here.
      return True
    for supported_on in policy['supported_on']:
      for supported_on_platform in supported_on['platforms']:
        if supported_on_platform in self.platforms:
          return True
    return False

  def CanBeRecommended(self, policy):
    '''Checks if the given policy can be recommended.'''
    return policy.get('features', {}).get('can_be_recommended', False)

  def CanBeMandatory(self, policy):
    '''Checks if the given policy can be mandatory.'''
    return policy.get('features', {}).get('can_be_mandatory', True)

  def IsPolicySupportedOnPlatform(self, policy, platform):
    '''Checks if |policy| is supported on |platform|.

    Args:
      policy: The dictionary of the policy.
      platform: The platform to check; one of 'win', 'mac', 'linux' or
        'chrome_os'.
    '''
    is_supported = lambda x: platform in x['platforms']
    return any(filter(is_supported, policy['supported_on']))

  def _GetPoliciesForWriter(self, group):
    '''Filters the list of policies in the passed group that are supported by
    the writer.

    Args:
      group: The dictionary of the policy group.

    Returns: The list of policies of the policy group that are compatible
      with the writer.
    '''
    if not 'policies' in group:
      return []
    result = []
    for policy in group['policies']:
      if self.IsPolicySupported(policy):
        result.append(policy)
    return result

  def Init(self):
    '''Initializes the writer. If the WriteTemplate method is overridden, then
    this method must be called as first step of each template generation
    process.
    '''
    pass

  def WriteTemplate(self, template):
    '''Writes the given template definition.

    Args:
      template: Template definition to write.

    Returns:
      Generated output for the passed template definition.
    '''
    self.messages = template['messages']
    self.Init()
    template['policy_definitions'] = \
        self.PreprocessPolicies(template['policy_definitions'])
    self.BeginTemplate()
    for policy in template['policy_definitions']:
      if policy['type'] == 'group':
        child_policies = self._GetPoliciesForWriter(policy)
        child_recommended_policies = filter(self.CanBeRecommended,
                                            child_policies)
        if child_policies:
          # Only write nonempty groups.
          self.BeginPolicyGroup(policy)
          for child_policy in child_policies:
            # Nesting of groups is currently not supported.
            self.WritePolicy(child_policy)
          self.EndPolicyGroup()
        if child_recommended_policies:
          self.BeginRecommendedPolicyGroup(policy)
          for child_policy in child_recommended_policies:
            self.WriteRecommendedPolicy(child_policy)
          self.EndRecommendedPolicyGroup()
      elif self.IsPolicySupported(policy):
        self.WritePolicy(policy)
        if self.CanBeRecommended(policy):
          self.WriteRecommendedPolicy(policy)
    self.EndTemplate()

    return self.GetTemplateText()

  def PreprocessPolicies(self, policy_list):
    '''Preprocesses a list of policies according to a given writer's needs.
    Preprocessing steps include sorting policies and stripping unneeded
    information such as groups (for writers that ignore them).
    Subclasses are encouraged to override this method, overriding
    implementations may call one of the provided specialized implementations.
    The default behaviour is to use SortPoliciesGroupsFirst().

    Args:
      policy_list: A list containing the policies to sort.

    Returns:
      The sorted policy list.
    '''
    return self.SortPoliciesGroupsFirst(policy_list)

  def WritePolicy(self, policy):
    '''Appends the template text corresponding to a policy into the
    internal buffer.

    Args:
      policy: The policy as it is found in the JSON file.
    '''
    raise NotImplementedError()

  def WriteRecommendedPolicy(self, policy):
    '''Appends the template text corresponding to a recommended policy into the
    internal buffer.

    Args:
      policy: The recommended policy as it is found in the JSON file.
    '''
    # TODO
    #raise NotImplementedError()
    pass

  def BeginPolicyGroup(self, group):
    '''Appends the template text corresponding to the beginning of a
    policy group into the internal buffer.

    Args:
      group: The policy group as it is found in the JSON file.
    '''
    pass

  def EndPolicyGroup(self):
    '''Appends the template text corresponding to the end of a
    policy group into the internal buffer.
    '''
    pass

  def BeginRecommendedPolicyGroup(self, group):
    '''Appends the template text corresponding to the beginning of a recommended
    policy group into the internal buffer.

    Args:
      group: The recommended policy group as it is found in the JSON file.
    '''
    pass

  def EndRecommendedPolicyGroup(self):
    '''Appends the template text corresponding to the end of a recommended
    policy group into the internal buffer.
    '''
    pass

  def BeginTemplate(self):
    '''Appends the text corresponding to the beginning of the whole
    template into the internal buffer.
    '''
    raise NotImplementedError()

  def EndTemplate(self):
    '''Appends the text corresponding to the end of the whole
    template into the internal buffer.
    '''
    pass

  def GetTemplateText(self):
    '''Gets the content of the internal template buffer.

    Returns:
      The generated template from the the internal buffer as a string.
    '''
    raise NotImplementedError()

  def SortPoliciesGroupsFirst(self, policy_list):
    '''Sorts a list of policies alphabetically. The order is the
    following: first groups alphabetically by caption, then other policies
    alphabetically by name. The order of policies inside groups is unchanged.

    Args:
      policy_list: The list of policies to sort. Sub-lists in groups will not
        be sorted.
    '''
    policy_list.sort(key=self.GetPolicySortingKeyGroupsFirst)
    return policy_list

  def FlattenGroupsAndSortPolicies(self, policy_list, sorting_key=None):
    '''Sorts a list of policies according to |sorting_key|, defaulting
    to alphabetical sorting if no key is given. If |policy_list| contains
    policies with type="group", it is flattened first, i.e. any groups' contents
    are inserted into the list as first-class elements and the groups are then
    removed.
    '''
    new_list = []
    for policy in policy_list:
      if policy['type'] == 'group':
        for grouped_policy in policy['policies']:
          new_list.append(grouped_policy)
      else:
        new_list.append(policy)
    if sorting_key == None:
      sorting_key = self.GetPolicySortingKeyName
    new_list.sort(key=sorting_key)
    return new_list

  def GetPolicySortingKeyName(self, policy):
    return policy['name']

  def GetPolicySortingKeyGroupsFirst(self, policy):
    '''Extracts a sorting key from a policy. These keys can be used for
    list.sort() methods to sort policies.
    See TemplateWriter.SortPolicies for usage.
    '''
    is_group = policy['type'] == 'group'
    if is_group:
      # Groups are sorted by caption.
      str_key = policy['caption']
    else:
      # Regular policies are sorted by name.
      str_key = policy['name']
    # Groups come before regular policies.
    return (not is_group, str_key)
