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

"""Objects for describing template code that can be generated from ukm.xml."""

import hashlib
import os
import re
import struct
from ukm_model import _EVENT_TYPE
from ukm_model import _METRIC_TYPE


def sanitize_name(name):
  s = re.sub('[^0-9a-zA-Z_]', '_', name)
  return s


def HashName(name):
  # This must match the hash function in //base/metrics/metrics_hashes.cc.
  # >Q: 8 bytes, big endian.
  return struct.unpack('>Q', hashlib.md5(name.encode()).digest()[:8])[0]


class FileInfo(object):
  def __init__(self, relpath, basename):
    self.dir_path = relpath
    self.guard_path = sanitize_name(os.path.join(relpath, basename)).upper()


class EventInfo(object):
  def __init__(self, json_obj):
    self.raw_name = json_obj['name']
    self.name = sanitize_name(json_obj['name'])
    self.hash = HashName(json_obj['name'])


class MetricInfo(object):
  def __init__(self, json_obj):
    self.raw_name = json_obj['name']
    self.name = sanitize_name(json_obj['name'])
    self.hash = HashName(json_obj['name'])


class Template(object):
  """Template for producing code from ukm.xml."""

  def __init__(self, basename, file_template, event_template, metric_template):
    self.basename = basename
    self.file_template = file_template
    self.event_template = event_template
    self.metric_template = metric_template

  def _StampMetricCode(self, file_info, event_info, metric):
    return self.metric_template.format(
        file=file_info,
        event=event_info,
        metric=MetricInfo(metric))

  def _StampEventCode(self, file_info, event):
    event_info = EventInfo(event)
    metric_code = "".join(
        self._StampMetricCode(file_info, event_info, metric)
        for metric in event[_METRIC_TYPE.tag])
    return self.event_template.format(
        file=file_info,
        event=event_info,
        metric_code=metric_code)

  def _StampFileCode(self, relpath, data):
    file_info = FileInfo(relpath, self.basename)
    event_code = "".join(
        self._StampEventCode(file_info, event)
        for event in data[_EVENT_TYPE.tag])
    return self.file_template.format(
        file=file_info,
        event_code=event_code)

  def WriteFile(self, outdir, relpath, data):
    """Generates code and writes it to a file.

    Args:
      relpath: The path to the file in the source tree.
      rootdir: The root of the path the file should be written to.
      data: The parsed ukm.xml data.
    """
    output = open(os.path.join(outdir, self.basename), 'w')
    output.write(self._StampFileCode(relpath, data))
    output.close()
