#!/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.

import copy
import re


def IsGroupOrAtomicGroup(policy):
  return policy['type'] == 'group' or policy['type'] == 'atomic_group'


class PolicyTemplateGenerator:
  '''Generates template text for a particular platform.

  This class is used to traverse a JSON structure from a .json template
  definition metafile and merge GUI message string definitions that come
  from a .grd resource tree onto it. After this, it can be used to output
  this data to policy template files using TemplateWriter objects.
  '''

  def _ImportMessage(self, msg_txt):
    msg_txt = msg_txt.decode('utf-8')
    lines = msg_txt.split('\n')

    # Strip any extra leading spaces, but keep useful indentation:
    min_leading_spaces = min(list(self._IterateLeadingSpaces(lines)) or [0])
    if min_leading_spaces > 0:
      lstrip_pattern = re.compile('^[ ]{1,%s}' % min_leading_spaces)
      lines = [lstrip_pattern.sub('', line) for line in lines]
    # Strip all trailing spaces:
    lines = [line.rstrip() for line in lines]
    return "\n".join(lines)

  def _IterateLeadingSpaces(self, lines):
    '''Yields the number of leading spaces on each line, skipping lines which
    have no leading spaces.'''
    for line in lines:
      match = re.search('^[ ]+', line)
      if match:
        yield len(match.group(0))

  def __init__(self, config, policy_data):
    '''Initializes this object with all the data necessary to output a
    policy template.

    Args:
      config: Writer configuration.
      policy_data: The list of defined policies and groups, as parsed from the
        policy metafile. See
          components/policy/resources/policy_templates.json
        for description and content.
            '''
    # List of all the policies. Create a copy since the data is modified.
    self._policy_data = copy.deepcopy(policy_data)
    # Localized messages to be inserted to the policy_definitions structure:
    self._messages = self._policy_data['messages']
    self._config = config
    for key in self._messages.keys():
      self._messages[key]['text'] = self._ImportMessage(
          self._messages[key]['text'])
    self._AddGroups(self._policy_data['policy_definitions'])
    self._AddAtomicGroups(self._policy_data['policy_definitions'],
                          self._policy_data['policy_atomic_group_definitions'])
    self._policy_data[
        'policy_atomic_group_definitions'] = self._ExpandAtomicGroups(
            self._policy_data['policy_definitions'],
            self._policy_data['policy_atomic_group_definitions'])
    self._ProcessPolicyList(
        self._policy_data['policy_atomic_group_definitions'])
    self._policy_data['policy_definitions'] = self._ExpandGroups(
        self._policy_data['policy_definitions'])
    self._policy_definitions = self._policy_data['policy_definitions']
    self._ProcessPolicyList(self._policy_definitions)

  def _ProcessSupportedOn(self, supported_on):
    '''Parses and converts the string items of the list of supported platforms
    into dictionaries.

    Args:
      supported_on: The list of supported platforms. E.g.:
        ['chrome.win:8-10', 'chrome_frame:10-']

    Returns:
      supported_on: The list with its items converted to dictionaries. E.g.:
      [{
        'product': 'chrome',
        'platforms': 'win',
        'since_version': '8',
        'until_version': '10'
      }, {
        'product': 'chrome_frame',
        'platforms': 'win',
        'since_version': '10',
        'until_version': ''
      }]
    '''
    result = []
    for supported_on_item in supported_on:
      product_platform_part, version_part = supported_on_item.split(':')

      if '.' in product_platform_part:
        product, platform = product_platform_part.split('.')
        if platform == '*':
          # e.g.: 'chrome.*:8-10'
          platforms = ['linux', 'mac', 'win']
        else:
          # e.g.: 'chrome.win:-10'
          platforms = [platform]
      else:
        # e.g.: 'chrome_frame:7-'
        product, platform = {
            'android': ('chrome', 'android'),
            'webview_android': ('webview', 'android'),
            'chrome_os': ('chrome_os', 'chrome_os'),
            'chrome_frame': ('chrome_frame', 'win'),
        }[product_platform_part]
        platforms = [platform]
      since_version, until_version = version_part.split('-')
      result.append({
          'product': product,
          'platforms': platforms,
          'since_version': since_version,
          'until_version': until_version
      })
    return result

  def _ProcessPolicy(self, policy):
    '''Processes localized message strings in a policy or a group.
     Also breaks up the content of 'supported_on' attribute into a list.

    Args:
      policy: The data structure of the policy or group, that will get message
        strings here.
    '''
    if policy['type'] != 'atomic_group':
      policy['desc'] = self._ImportMessage(policy['desc'])
    policy['caption'] = self._ImportMessage(policy['caption'])
    if 'label' in policy:
      policy['label'] = self._ImportMessage(policy['label'])
    if 'arc_support' in policy:
      policy['arc_support'] = self._ImportMessage(policy['arc_support'])

    if IsGroupOrAtomicGroup(policy):
      self._ProcessPolicyList(policy['policies'])
    elif policy['type'] in ('string-enum', 'int-enum', 'string-enum-list'):
      # Iterate through all the items of an enum-type policy, and add captions.
      for item in policy['items']:
        item['caption'] = self._ImportMessage(item['caption'])
    if not IsGroupOrAtomicGroup(policy):
      if not 'label' in policy:
        # If 'label' is not specified, then it defaults to 'caption':
        policy['label'] = policy['caption']
      policy['supported_on'] = self._ProcessSupportedOn(policy['supported_on'])

  def _ProcessPolicyList(self, policy_list):
    '''Adds localized message strings to each item in a list of policies and
    groups. Also breaks up the content of 'supported_on' attributes into lists
    of dictionaries.

    Args:
      policy_list: A list of policies and groups. Message strings will be added
        for each item and to their child items, recursively.
    '''
    for policy in policy_list:
      self._ProcessPolicy(policy)

  def GetTemplateText(self, template_writer):
    '''Generates the text of the template from the arguments given
    to the constructor, using a given TemplateWriter.

    Args:
      template_writer: An object implementing TemplateWriter. Its methods
        are called here for each item of self._policy_data.

    Returns:
      The text of the generated template.
    '''
    # Create a copy, so that writers can't screw up subsequent writers.
    policy_data_copy = copy.deepcopy(self._policy_data)
    return template_writer.WriteTemplate(policy_data_copy)


  def _AddGroups(self, policy_list):
    '''Adds a 'group' field, which is set to be the group's name, to the
       policies that are part of a group.

    Args:
      policy_list: A list of policies and groups whose policies will have a
      'group' field added.
    '''
    groups = [policy for policy in policy_list if policy['type'] == 'group']
    policy_lookup = {
        policy['name']: policy
        for policy in policy_list
        if not IsGroupOrAtomicGroup(policy)
    }
    for group in groups:
      for policy_name in group['policies']:
        policy_lookup[policy_name]['group'] = group['name']

  def _AddAtomicGroups(self, policy_list, policy_atomic_groups):
    '''Adds an 'atomic_group' field to the policies that are part of an atomic
    group.

    Args:
      policy_list: A list of policies and groups.
      policy_atomic_groups: A list of policy atomic groups
    '''
    policy_lookup = {
        policy['name']: policy
        for policy in policy_list
        if not IsGroupOrAtomicGroup(policy)
    }
    for group in policy_atomic_groups:
      for policy_name in group['policies']:
        policy_lookup[policy_name]['atomic_group'] = group['name']
        break

  def _ExpandAtomicGroups(self, policy_list, policy_atomic_groups):
    '''Replaces policies names inside atomic group definitions for actual
    policies definitions.

    Args:
      policy_list: A list of policies and groups.

    Returns:
      Modified policy_list
    '''
    policies = [
        policy for policy in policy_list if not IsGroupOrAtomicGroup(policy)
    ]
    for group in policy_atomic_groups:
      group['type'] = 'atomic_group'
    expanded = self._ExpandGroups(policies + policy_atomic_groups)
    expanded = [policy for policy in expanded if IsGroupOrAtomicGroup(policy)]
    return copy.deepcopy(expanded)

  def _ExpandGroups(self, policy_list):
    '''Replaces policies names inside group definitions for actual policies
    definitions. If policy does not belong to any group, leave it as is.

    Args:
      policy_list: A list of policies and groups.

    Returns:
      Modified policy_list
    '''
    groups = [policy for policy in policy_list if IsGroupOrAtomicGroup(policy)]
    policies = {
        policy['name']: policy
        for policy in policy_list
        if not IsGroupOrAtomicGroup(policy)
    }
    policies_in_groups = set()
    result_policies = []
    for group in groups:
      group_policies = group['policies']
      expanded_policies = [
          policies[policy_name] for policy_name in group_policies
      ]
      assert policies_in_groups.isdisjoint(group_policies)
      policies_in_groups.update(group_policies)
      group['policies'] = expanded_policies
      result_policies.append(group)

    result_policies.extend([
        policy for policy in policy_list if not IsGroupOrAtomicGroup(policy) and
        policy['name'] not in policies_in_groups
    ])
    return result_policies
