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

# If this presubmit check fails or misbehaves, please complain to
# mnissler@chromium.org, pastarmovj@chromium.org or joaodasilva@chromium.org.

import itertools
import sys
import xml.dom.minidom

def _GetPolicyTemplates(template_path):
  # Read list of policies in the template. eval() is used instead of a JSON
  # parser because policy_templates.json is not quite JSON, and uses some
  # python features such as #-comments and '''strings'''. policy_templates.json
  # is actually maintained as a python dictionary.
  with open(template_path) as f:
    template_data = eval(f.read(), {})
  policies = ( policy
               for policy in template_data['policy_definitions']
               if policy['type'] != 'group' )
  groups = ( policy['policies']
             for policy in template_data['policy_definitions']
             if policy['type'] == 'group' )
  subpolicies = ( policy for group in groups for policy in group )
  return list(itertools.chain(policies, subpolicies))

def _CheckPolicyTemplatesSyntax(input_api, output_api):
  local_path = input_api.PresubmitLocalPath()
  filepath = input_api.os_path.join(local_path, 'policy_templates.json')
  if any(f.AbsoluteLocalPath() == filepath
         for f in input_api.AffectedFiles()):
    old_sys_path = sys.path
    try:
      tools_path = input_api.os_path.normpath(
          input_api.os_path.join(local_path, input_api.os_path.pardir, 'tools'))
      sys.path = [ tools_path ] + sys.path
      # Optimization: only load this when it's needed.
      import syntax_check_policy_template_json
      checker = syntax_check_policy_template_json.PolicyTemplateChecker()
      if checker.Run([], filepath) > 0:
        return [output_api.PresubmitError('Syntax error(s) in file:',
                                          [filepath])]
    finally:
      sys.path = old_sys_path
  return []


def _CheckPolicyTestCases(input_api, output_api, policies):
  # Read list of policies in chrome/test/data/policy/policy_test_cases.json.
  root = input_api.change.RepositoryRoot()
  policy_test_cases_file = input_api.os_path.join(
      root, 'chrome', 'test', 'data', 'policy', 'policy_test_cases.json')
  test_names = input_api.json.load(open(policy_test_cases_file)).keys()
  tested_policies = frozenset(name for name in test_names if name[:2] != '--')
  policy_names = frozenset(policy['name'] for policy in policies)

  # Finally check if any policies are missing.
  missing = policy_names - tested_policies
  extra = tested_policies - policy_names
  error_missing = ('Policy \'%s\' was added to policy_templates.json but not '
                   'to src/chrome/test/data/policy/policy_test_cases.json. '
                   'Please update both files.')
  error_extra = ('Policy \'%s\' is tested by '
                 'src/chrome/test/data/policy/policy_test_cases.json but is not'
                 ' defined in policy_templates.json. Please update both files.')
  results = []
  for policy in missing:
    results.append(output_api.PresubmitError(error_missing % policy))
  for policy in extra:
    results.append(output_api.PresubmitError(error_extra % policy))
  return results


def _CheckPolicyHistograms(input_api, output_api, policies):
  root = input_api.change.RepositoryRoot()
  histograms = input_api.os_path.join(
      root, 'tools', 'metrics', 'histograms', 'histograms.xml')
  with open(histograms) as f:
    tree = xml.dom.minidom.parseString(f.read())
  enums = (tree.getElementsByTagName('histogram-configuration')[0]
               .getElementsByTagName('enums')[0]
               .getElementsByTagName('enum'))
  policy_enum = [e for e in enums
                 if e.getAttribute('name') == 'EnterprisePolicies'][0]
  policy_ids = frozenset([int(e.getAttribute('value'))
                          for e in policy_enum.getElementsByTagName('int')])

  error_missing = ('Policy \'%s\' was added to policy_templates.json but not '
                   'to src/tools/metrics/histograms/histograms.xml. '
                   'Please update both files.')
  results = []
  for policy in policies:
    if policy['id'] not in policy_ids:
      results.append(output_api.PresubmitError(error_missing % policy['name']))
  return results


def _CommonChecks(input_api, output_api):
  results = []
  results.extend(_CheckPolicyTemplatesSyntax(input_api, output_api))

  os_path = input_api.os_path
  local_path = input_api.PresubmitLocalPath()
  template_path = os_path.join(local_path, 'policy_templates.json')
  affected_files = input_api.AffectedFiles()
  if any(f.AbsoluteLocalPath() == template_path for f in affected_files):
    policies = _GetPolicyTemplates(template_path)
    results.extend(_CheckPolicyTestCases(input_api, output_api, policies))
    results.extend(_CheckPolicyHistograms(input_api, output_api, policies))

  return results


def CheckChangeOnUpload(input_api, output_api):
  return _CommonChecks(input_api, output_api)


def CheckChangeOnCommit(input_api, output_api):
  return _CommonChecks(input_api, output_api)
