# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS 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 to be generated from structured.xml."""

import hashlib
import os
import re
import struct


class Util:
    """Helpers for generating C++."""

    @staticmethod
    def sanitize_name(name):
        return re.sub("[^0-9a-zA-Z_]", "_", name)

    @staticmethod
    def camel_to_snake(name):
        pat = "((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))"
        return re.sub(pat, r"_\1", name).lower()

    @staticmethod
    def hash_name(name):
        # This must match the hash function in chromium's
        # //base/metrics/metric_hashes.cc. >Q means 8 bytes, big endian.
        name = name.encode("utf-8")
        md5 = hashlib.md5(name)
        return struct.unpack(">Q", md5.digest()[:8])[0]

    @staticmethod
    def event_name_hash(project_name, event_name):
        """Make the name hash for an event.

        This gets uploaded in the StructuredEventProto.event_name_hash field. It
        is the sole means of recording which event from structured.xml a
        StructuredEventProto instance represents.

        To avoid naming collisions, it must contain three pieces of information:
         - the name of the event itself
         - the name of the event's project, to avoid collisions with events of
           the same name in other projects
         - an identifier that this comes from chromeos, to avoid collisions with
           events and projects of the same name defined in chromium's
           structured.xml

        This must use sanitized names for the project and event.
        """
        event_name = Util.sanitize_name(event_name)
        project_name = Util.sanitize_name(project_name)
        return Util.hash_name(f"cros::{project_name}::{event_name}")


class FileInfo:
    """Codegen-related info about a file."""

    def __init__(self, dirname, basename):
        self.dirname = dirname
        self.basename = basename
        self.filepath = os.path.join(dirname, basename)

        # This takes the last three components of the filepath for use in the
        # header guard, ie. METRICS_STRUCTURED_STRUCTURED_EVENTS_H_
        relative_path = os.sep.join(self.filepath.split(os.sep)[-3:])
        self.guard_path = Util.sanitize_name(relative_path).upper()


class ProjectInfo:
    """Codegen-related info about a project."""

    def __init__(self, project):
        self.name = Util.sanitize_name(project.name)
        self.namespace = Util.camel_to_snake(self.name)
        self.name_hash = Util.hash_name(self.name)

        # Set ID Type.
        if project.id == "uma":
            self.id_type = "kUmaId"
        elif project.id == "per-project":
            self.id_type = "kProjectId"
        elif project.id == "none":
            self.id_type = "kUnidentified"

        # Set event type. This is inferred by checking all metrics within the
        # project. If any of a project's metrics is a raw string, then its
        # events are considered raw string events, even if they also contain
        # non-strings.
        self.event_type = "REGULAR"
        for event in project.events:
            for metric in event.metrics:
                if metric.type == "raw-string":
                    self.event_type = "RAW_STRING"
                    break


class EventInfo:
    """Codegen-related info about an event."""

    def __init__(self, event, project_info):
        self.name = Util.sanitize_name(event.name)
        self.name_hash = Util.event_name_hash(project_info.name, self.name)


class MetricInfo:
    """Codegen-related info about a metric."""

    def __init__(self, metric):
        self.name = Util.sanitize_name(metric.name)
        self.hash = Util.hash_name(metric.name)

        if metric.type == "hmac-string":
            self.setter_type = "std::string&"
            self.setter = "AddHmacMetric"
            self.getter_type = "std::string"
            self.getter = "GetHmacMetricForTest"
        elif metric.type == "int":
            self.setter_type = "int64_t"
            self.setter = "AddIntMetric"
            self.getter_type = "int64_t"
            self.getter = "GetIntMetricForTest"
        elif metric.type == "raw-string":
            self.setter_type = "std::string&"
            self.setter = "AddRawStringMetric"
            self.getter_type = "std::string"
            self.getter = "GetRawStringMetricForTest"
        elif metric.type == "double":
            self.setter_type = "double"
            self.setter = "AddDoubleMetric"
            self.getter_type = "double"
            self.getter = "GetDoubleMetricForTest"
        else:
            raise ValueError("Invalid metric type.")


class Template:
    """Template for producing code from structured.xml."""

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

    def write_file(self):
        file_info = FileInfo(self.dirname, self.basename)
        with open(file_info.filepath, "w") as f:
            f.write(self._stamp_file(file_info))

    def _stamp_file(self, file_info):
        project_code = "".join(
            self._stamp_project(file_info, p) for p in self.model.projects
        )

        project_names = sorted([p.name for p in self.model.projects])
        project_hashes_list = [
            f"UINT64_C({Util.hash_name(n)})" for n in project_names
        ]
        project_hashes_literal = "{" + ", ".join(project_hashes_list) + "}"

        return self.file_template.format(
            file=file_info,
            project_code=project_code,
            project_hashes=project_hashes_literal,
        )

    def _stamp_project(self, file_info, project):
        project_info = ProjectInfo(project)
        event_code = "".join(
            self._stamp_event(file_info, project_info, event)
            for event in project.events
        )
        return self.project_template.format(
            file=file_info, project=project_info, event_code=event_code
        )

    def _stamp_event(self, file_info, project_info, event):
        event_info = EventInfo(event, project_info)
        metric_code = "".join(
            self._stamp_metric(file_info, event_info, metric)
            for metric in event.metrics
        )
        return self.event_template.format(
            file=file_info,
            project=project_info,
            event=event_info,
            metric_code=metric_code,
        )

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