#!/usr/bin/env python3
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Prints all histogram names."""

from __future__ import print_function

import argparse
import os
import re
import subprocess
import sys
import tempfile
import io
from typing import Iterable, Set

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

import extract_histograms
import histogram_paths
import merge_xml


# Used in android_webview/java/res/raw/histograms_allowlist_check.py.
def get_names(xml_files):
  """Returns all histogram names generated from a list of xml files.

  Args:
    xml_files: A list of open file objects containing histogram definitions.
  Returns:
    The set of histogram names.
  """
  doc = merge_xml.MergeFiles(files=xml_files)
  histograms, had_errors = extract_histograms.ExtractHistogramsFromDom(doc)
  if had_errors:
    raise ValueError("Error parsing inputs.")
  return set(extract_histograms.ExtractNames(histograms))


def get_names_from_contents(contents: Iterable[str]) -> Set[str]:
  """Returns all histogram names from the given contents.

  This function is different from get_names() in that it does not make
  additional checks against the given contents. Note: it currently doesn't
  handle go/patterned-histogram names.

  Args:
    contents: An iterable of strings from the raw histograms xml file.

  Returns:
    The set of histogram names.
  """
  # contents is an iterator, so convert to list to be able to reuse it.
  contents_list = list(contents)
  if not contents_list:
    return set()

  doc = merge_xml.MergeFiles(files=[io.StringIO('\n'.join(contents_list))])
  xml_utils.NormalizeAllAttributeValues(doc)
  histograms_tree = xml_utils.GetTagSubTree(doc, 'histograms', 2)
  histogram_names = set()

  for histogram in xml_utils.IterElementsWithTag(histograms_tree, 'histogram'):
    histogram_names.add(histogram.getAttribute('name'))
  return histogram_names


def histogram_xml_files():
  return [open(f, encoding="utf-8") for f in histogram_paths.ALL_XMLS]


def get_histogram_diff(revision):
  """Returns the added / removed histogram names relative to git revision

  Args:
    revision: A git revision as described in
      https://git-scm.com/docs/gitrevisions
  Returns:
    A tuple of (added names, removed names), where each entry is sorted in
    ascending order.
  """

  def get_file_at_revision(path):
    """Returns a file-like object containing |path|'s content at |revision|"""
    obj = "%s:%s" % (revision, path)
    contents = subprocess.check_output(
        ("git", "cat-file", "--textconv", obj)).decode()

    # Just store the contents in memory. histograms.xml is big, but it isn't
    # _that_ big.
    return io.StringIO(contents)

  prev_files = []
  for p in histogram_paths.ALL_XMLS_RELATIVE:
    try:
      prev_files.append(get_file_at_revision(p))
    except subprocess.CalledProcessError:
      # Paths might not exist in the provided revision.
      continue

  current_histogram_names = get_names(histogram_xml_files())
  prev_histogram_names = get_names(prev_files)

  added_names = sorted(list(current_histogram_names - prev_histogram_names))
  removed_names = sorted(list(prev_histogram_names - current_histogram_names))
  return (added_names, removed_names)


def _print_diff_names(revision):
  added_names, removed_names = get_histogram_diff(revision)
  print("%d histograms added:" % len(added_names))
  for name in added_names:
    print(name)

  print("%d histograms removed:" % len(removed_names))
  for name in removed_names:
    print(name)


def main(argv):
  parser = argparse.ArgumentParser(description='Print histogram names.')
  parser.add_argument('--diff',
                      type=str,
                      help='Git revision to diff against (e.g. HEAD~)')
  args = parser.parse_args(argv[1:])
  if args.diff is not None:
    _print_diff_names(args.diff)
  else:
    name_set = get_names(histogram_xml_files())
    for name in sorted(list(name_set)):
      print(name)


if __name__ == '__main__':
  main(sys.argv)
