# -*- coding: utf-8 -*-
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Utilities for parsing structured.xml.

Functions in this module raise an error if constraints on the format of the
structured.xml file are not met.

Functions use the concept of 'compound' and 'text' XML nodes.
 - compound nodes can have attributes and child nodes, but no text
 - text nodes can have text, but no attributes or child nodes
"""

import collections
import re


def error(elem, msg):
    """Raise a nicely formatted error with some context."""
    name = elem.attrib.get('name', None)
    name = name + ' ' if name else ''
    msg = 'Structured metrics error, {} node {}: {}.'.format(
            elem.tag, name, msg)
    raise ValueError(msg)


def get_attr(elem, tag, regex=None):
    """Get an attribute.

    Error if it is missing, optionally error if it doesn't match the provided
    regex.
    """
    attr = elem.attrib.get(tag, None)
    if not attr:
        error(elem, "missing attribute '{}'".format(tag))
    if regex and not re.match(regex, attr):
        error(elem, ("has '{}' attribute '{}' which does "
                     "not match regex '{}'").format(tag, attr, regex))
    return attr


def get_compound_children(elem, tag):
    """Get all child nodes of `elem` with tag `tag`.

    Error if none exist, or a child is not a compound node.
    """
    children = elem.findall(tag)
    if not children:
        error(elem, "missing node '{}'".format(tag))
    for child in children:
        if child.text.strip():
            error(child, "contains text, but shouldn't")
    return children


def get_compound_child(elem, tag):
    """Get the child of `elem` with tag `tag`.

    Error if there isn't exactly one matching child, or it isn't compound.
    """
    children = elem.findall(tag)
    if len(children) != 1:
        error(elem, "needs exactly one '{}' node".format(tag))
    return children[0]


def get_text_children(elem, tag, regex=None):
    """Get the text of all child nodes of `elem` with tag `tag`.

    Error if none exist, or a child is not a text node. Optionally ensure the
    text matches `regex`.
    """
    children = elem.findall(tag)
    if not children:
        error(elem, "missing node '{}'".format(tag))

    result = []
    for child in children:
        check_attributes(child, set())
        check_children(child, set())
        text = child.text.strip()
        if not text:
            error(elem, "missing text in '{}'".format(tag))
        if regex and not re.match(regex, text):
            error(elem, ("has '{}' node '{}' which does "
                         "not match regex '{}'").format(tag, text, regex))
        result.append(text)
    return result


def get_text_child(elem, tag, regex=None):
    """Get the text of the child of `elem` with tag `tag`.

    Error if there isn't exactly one matching child, or it isn't a text node.
    Optionally ensure the text matches `regex`.
    """
    result = get_text_children(elem, tag, regex)
    if len(result) != 1:
        error(elem, "needs exactly one '{}' node".format(tag))
    return result[0]


def check_attributes(elem, expected_attrs):
    """Ensure `elem` has no attributes except those in `expected_attrs`."""
    actual_attrs = elem.attrib.keys()
    unexpected_attrs = actual_attrs - set(expected_attrs)
    if unexpected_attrs:
        attrs = ' '.join(unexpected_attrs)
        error(elem, 'has unexpected attributes: ' + attrs)


def check_children(elem, expected_children):
    """Ensure `elem` has no children without tags in `expected_children`."""
    actual_children = {child.tag for child in elem}
    unexpected_children = actual_children - set(expected_children)
    if unexpected_children:
        children = ' '.join(unexpected_children)
        error(elem, 'has unexpected nodes: ' + children)


def check_child_names_unique(elem, tag):
    """Ensure uniqueness of the 'name' of all children of `elem` with `tag`."""
    names = [child.attrib.get('name', None)
                     for child in elem if child.tag == tag]
    name_counts = collections.Counter(names)
    has_duplicates = any(c > 1 for c in name_counts.values())
    if has_duplicates:
        error(elem, 'has {} nodes with duplicate names'.format(tag))
