# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# """Model objects for ukm.xml contents."""

import os
import sys

sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'common'))
import models

# Model definitions for ukm.xml content
_OBSOLETE_TYPE = models.TextNodeType('obsolete')
_OWNER_TYPE = models.TextNodeType('owner', single_line=True)
_SUMMARY_TYPE = models.TextNodeType('summary')

# A key for sorting XML nodes by the value of |attribute|.
_LOWERCASE_FN = lambda attribute: (lambda node: node.get(attribute).lower())
# A constant function as the sorting key for nodes whose orderings should be
# kept as given in the XML file within their parent node.
_KEEP_ORDER = lambda node: 1

_ENUMERATION_TYPE = models.ObjectNodeType(
    'enumeration',
    attributes=[],
    single_line=True)

_QUANTILES_TYPE = models.ObjectNodeType(
    'quantiles',
    attributes=[
      ('type', str, None),
    ],
    single_line=True)

_INDEX_TYPE = models.ObjectNodeType(
    'index',
    attributes=[
      ('fields', str, None),
    ],
    single_line=True)

_STATISTICS_TYPE = models.ObjectNodeType(
    'statistics',
    attributes=[
        ('export', str, r'(?i)^(|true|false)$'),
    ],
    children=[
        models.ChildType(_QUANTILES_TYPE.tag, _QUANTILES_TYPE, multiple=False),
        models.ChildType(_ENUMERATION_TYPE.tag,
                         _ENUMERATION_TYPE,
                         multiple=False),
    ])

_HISTORY_TYPE =  models.ObjectNodeType(
    'history',
    attributes=[],
    alphabetization=[
        (_INDEX_TYPE.tag, _LOWERCASE_FN('fields')),
        (_STATISTICS_TYPE.tag, _KEEP_ORDER),
    ],
    children=[
        models.ChildType(_INDEX_TYPE.tag, _INDEX_TYPE, multiple=True),
        models.ChildType(_STATISTICS_TYPE.tag, _STATISTICS_TYPE, multiple=True),
    ])

_AGGREGATION_TYPE =  models.ObjectNodeType(
    'aggregation',
    attributes=[],
    children=[
        models.ChildType(_HISTORY_TYPE.tag, _HISTORY_TYPE, multiple=False),
    ])

_METRIC_TYPE =  models.ObjectNodeType(
    'metric',
    attributes=[
      ('name', str, r'^[A-Za-z0-9_.]+$'),
      ('semantic_type', str, None),
      ('enum', str, None),
    ],
    alphabetization=[
        (_OBSOLETE_TYPE.tag, _KEEP_ORDER),
        (_OWNER_TYPE.tag, _KEEP_ORDER),
        (_SUMMARY_TYPE.tag, _KEEP_ORDER),
        (_AGGREGATION_TYPE.tag, _KEEP_ORDER),
    ],
    children=[
        models.ChildType(_OBSOLETE_TYPE.tag, _OBSOLETE_TYPE, multiple=False),
        models.ChildType(_OWNER_TYPE.tag, _OWNER_TYPE, multiple=True),
        models.ChildType(_SUMMARY_TYPE.tag, _SUMMARY_TYPE, multiple=False),
        models.ChildType(
            _AGGREGATION_TYPE.tag, _AGGREGATION_TYPE, multiple=True),
    ])

_EVENT_TYPE = models.ObjectNodeType('event',
                                    attributes=[
                                        ('name', str, r'^[A-Za-z0-9.]+$'),
                                        ('singular', str,
                                         r'(?i)^(|true|false)$'),
                                    ],
                                    alphabetization=[
                                        (_OBSOLETE_TYPE.tag, _KEEP_ORDER),
                                        (_OWNER_TYPE.tag, _KEEP_ORDER),
                                        (_SUMMARY_TYPE.tag, _KEEP_ORDER),
                                        (_METRIC_TYPE.tag,
                                         _LOWERCASE_FN('name')),
                                    ],
                                    extra_newlines=(1, 1, 1),
                                    children=[
                                        models.ChildType(_OBSOLETE_TYPE.tag,
                                                         _OBSOLETE_TYPE,
                                                         multiple=False),
                                        models.ChildType(_OWNER_TYPE.tag,
                                                         _OWNER_TYPE,
                                                         multiple=True),
                                        models.ChildType(_SUMMARY_TYPE.tag,
                                                         _SUMMARY_TYPE,
                                                         multiple=False),
                                        models.ChildType(_METRIC_TYPE.tag,
                                                         _METRIC_TYPE,
                                                         multiple=True),
                                    ])

_UKM_CONFIGURATION_TYPE = models.ObjectNodeType(
    'ukm-configuration',
    alphabetization=[(_EVENT_TYPE.tag, _LOWERCASE_FN('name'))],
    extra_newlines=(2, 1, 1),
    indent=False,
    children=[
        models.ChildType(_EVENT_TYPE.tag, _EVENT_TYPE, multiple=True),
    ])

UKM_XML_TYPE = models.DocumentType(_UKM_CONFIGURATION_TYPE)

def PrettifyXML(original_xml):
  """Parses the original xml and return a pretty printed version.

  Args:
    original_xml: A string containing the original xml file contents.

  Returns:
    A pretty-printed xml string, or None if the config contains errors.
  """
  config = UKM_XML_TYPE.Parse(original_xml)
  return UKM_XML_TYPE.PrettyPrint(config)


def IsNotObsolete(node):
  """Checks if the given node contains a child <obsolete> node."""
  return _OBSOLETE_TYPE.tag not in node
