#!/usr/bin/env python3
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
"""Convert directories of JSON events to C code."""
import argparse
import csv
from functools import lru_cache
import json
import metric
import os
import sys
from typing import (Callable, Dict, Optional, Sequence, Set, Tuple)
import collections

# Global command line arguments.
_args = None
# List of regular event tables.
_event_tables = []
# List of event tables generated from "/sys" directories.
_sys_event_tables = []
# List of regular metric tables.
_metric_tables = []
# List of metric tables generated from "/sys" directories.
_sys_metric_tables = []
# Mapping between sys event table names and sys metric table names.
_sys_event_table_to_metric_table_mapping = {}
# Map from an event name to an architecture standard
# JsonEvent. Architecture standard events are in json files in the top
# f'{_args.starting_dir}/{_args.arch}' directory.
_arch_std_events = {}
# Events to write out when the table is closed
_pending_events = []
# Name of events table to be written out
_pending_events_tblname = None
# Metrics to write out when the table is closed
_pending_metrics = []
# Name of metrics table to be written out
_pending_metrics_tblname = None
# Global BigCString shared by all structures.
_bcs = None
# Map from the name of a metric group to a description of the group.
_metricgroups = {}
# Order specific JsonEvent attributes will be visited.
_json_event_attributes = [
    # cmp_sevent related attributes.
    'name', 'topic', 'desc',
    # Seems useful, put it early.
    'event',
    # Short things in alphabetical order.
    'compat', 'deprecated', 'perpkg', 'unit',
    # Longer things (the last won't be iterated over during decompress).
    'long_desc'
]

# Attributes that are in pmu_metric rather than pmu_event.
_json_metric_attributes = [
    'metric_name', 'metric_group', 'metric_expr', 'metric_threshold',
    'desc', 'long_desc', 'unit', 'compat', 'metricgroup_no_group',
    'default_metricgroup_name', 'aggr_mode', 'event_grouping'
]
# Attributes that are bools or enum int values, encoded as '0', '1',...
_json_enum_attributes = ['aggr_mode', 'deprecated', 'event_grouping', 'perpkg']

def removesuffix(s: str, suffix: str) -> str:
  """Remove the suffix from a string

  The removesuffix function is added to str in Python 3.9. We aim for 3.6
  compatibility and so provide our own function here.
  """
  return s[0:-len(suffix)] if s.endswith(suffix) else s


def file_name_to_table_name(prefix: str, parents: Sequence[str],
                            dirname: str) -> str:
  """Generate a C table name from directory names."""
  tblname = prefix
  for p in parents:
    tblname += '_' + p
  tblname += '_' + dirname
  return tblname.replace('-', '_')


def c_len(s: str) -> int:
  """Return the length of s a C string

  This doesn't handle all escape characters properly. It first assumes
  all \\ are for escaping, it then adjusts as it will have over counted
  \\. The code uses \000 rather than \0 as a terminator as an adjacent
  number would be folded into a string of \0 (ie. "\0" + "5" doesn't
  equal a terminator followed by the number 5 but the escape of
  \05). The code adjusts for \000 but not properly for all octal, hex
  or unicode values.
  """
  try:
    utf = s.encode(encoding='utf-8',errors='strict')
  except:
    print(f'broken string {s}')
    raise
  return len(utf) - utf.count(b'\\') + utf.count(b'\\\\') - (utf.count(b'\\000') * 2)

class BigCString:
  """A class to hold many strings concatenated together.

  Generating a large number of stand-alone C strings creates a large
  number of relocations in position independent code. The BigCString
  is a helper for this case. It builds a single string which within it
  are all the other C strings (to avoid memory issues the string
  itself is held as a list of strings). The offsets within the big
  string are recorded and when stored to disk these don't need
  relocation. To reduce the size of the string further, identical
  strings are merged. If a longer string ends-with the same value as a
  shorter string, these entries are also merged.
  """
  strings: Set[str]
  big_string: Sequence[str]
  offsets: Dict[str, int]
  insert_number: int
  insert_point: Dict[str, int]
  metrics: Set[str]

  def __init__(self):
    self.strings = set()
    self.insert_number = 0;
    self.insert_point = {}
    self.metrics = set()

  def add(self, s: str, metric: bool) -> None:
    """Called to add to the big string."""
    if s not in self.strings:
      self.strings.add(s)
      self.insert_point[s] = self.insert_number
      self.insert_number += 1
      if metric:
        self.metrics.add(s)

  def compute(self) -> None:
    """Called once all strings are added to compute the string and offsets."""

    folded_strings = {}
    # Determine if two strings can be folded, ie. let 1 string use the
    # end of another. First reverse all strings and sort them.
    sorted_reversed_strings = sorted([x[::-1] for x in self.strings])

    # Strings 'xyz' and 'yz' will now be [ 'zy', 'zyx' ]. Scan forward
    # for each string to see if there is a better candidate to fold it
    # into, in the example rather than using 'yz' we can use'xyz' at
    # an offset of 1. We record which string can be folded into which
    # in folded_strings, we don't need to record the offset as it is
    # trivially computed from the string lengths.
    for pos,s in enumerate(sorted_reversed_strings):
      best_pos = pos
      for check_pos in range(pos + 1, len(sorted_reversed_strings)):
        if sorted_reversed_strings[check_pos].startswith(s):
          best_pos = check_pos
        else:
          break
      if pos != best_pos:
        folded_strings[s[::-1]] = sorted_reversed_strings[best_pos][::-1]

    # Compute reverse mappings for debugging.
    fold_into_strings = collections.defaultdict(set)
    for key, val in folded_strings.items():
      if key != val:
        fold_into_strings[val].add(key)

    # big_string_offset is the current location within the C string
    # being appended to - comments, etc. don't count. big_string is
    # the string contents represented as a list. Strings are immutable
    # in Python and so appending to one causes memory issues, while
    # lists are mutable.
    big_string_offset = 0
    self.big_string = []
    self.offsets = {}

    def string_cmp_key(s: str) -> Tuple[bool, int, str]:
      return (s in self.metrics, self.insert_point[s], s)

    # Emit all strings that aren't folded in a sorted manner.
    for s in sorted(self.strings, key=string_cmp_key):
      if s not in folded_strings:
        self.offsets[s] = big_string_offset
        self.big_string.append(f'/* offset={big_string_offset} */ "')
        self.big_string.append(s)
        self.big_string.append('"')
        if s in fold_into_strings:
          self.big_string.append(' /* also: ' + ', '.join(fold_into_strings[s]) + ' */')
        self.big_string.append('\n')
        big_string_offset += c_len(s)
        continue

    # Compute the offsets of the folded strings.
    for s in folded_strings.keys():
      assert s not in self.offsets
      folded_s = folded_strings[s]
      self.offsets[s] = self.offsets[folded_s] + c_len(folded_s) - c_len(s)

_bcs = BigCString()

class JsonEvent:
  """Representation of an event loaded from a json file dictionary."""

  def __init__(self, jd: dict):
    """Constructor passed the dictionary of parsed json values."""

    def llx(x: int) -> str:
      """Convert an int to a string similar to a printf modifier of %#llx."""
      return str(x) if x >= 0 and x < 10 else hex(x)

    def fixdesc(s: str) -> str:
      """Fix formatting issue for the desc string."""
      if s is None:
        return None
      return removesuffix(removesuffix(removesuffix(s, '.  '),
                                       '. '), '.').replace('\n', '\\n').replace(
                                           '\"', '\\"').replace('\r', '\\r')

    def convert_aggr_mode(aggr_mode: str) -> Optional[str]:
      """Returns the aggr_mode_class enum value associated with the JSON string."""
      if not aggr_mode:
        return None
      aggr_mode_to_enum = {
          'PerChip': '1',
          'PerCore': '2',
      }
      return aggr_mode_to_enum[aggr_mode]

    def convert_metric_constraint(metric_constraint: str) -> Optional[str]:
      """Returns the metric_event_groups enum value associated with the JSON string."""
      if not metric_constraint:
        return None
      metric_constraint_to_enum = {
          'NO_GROUP_EVENTS': '1',
          'NO_GROUP_EVENTS_NMI': '2',
          'NO_NMI_WATCHDOG': '2',
          'NO_GROUP_EVENTS_SMT': '3',
      }
      return metric_constraint_to_enum[metric_constraint]

    def lookup_msr(num: str) -> Optional[str]:
      """Converts the msr number, or first in a list to the appropriate event field."""
      if not num:
        return None
      msrmap = {
          0x3F6: 'ldlat=',
          0x1A6: 'offcore_rsp=',
          0x1A7: 'offcore_rsp=',
          0x3F7: 'frontend=',
      }
      return msrmap[int(num.split(',', 1)[0], 0)]

    def real_event(name: str, event: str) -> Optional[str]:
      """Convert well known event names to an event string otherwise use the event argument."""
      fixed = {
          'inst_retired.any': 'event=0xc0,period=2000003',
          'inst_retired.any_p': 'event=0xc0,period=2000003',
          'cpu_clk_unhalted.ref': 'event=0x0,umask=0x03,period=2000003',
          'cpu_clk_unhalted.thread': 'event=0x3c,period=2000003',
          'cpu_clk_unhalted.core': 'event=0x3c,period=2000003',
          'cpu_clk_unhalted.thread_any': 'event=0x3c,any=1,period=2000003',
      }
      if not name:
        return None
      if name.lower() in fixed:
        return fixed[name.lower()]
      return event

    def unit_to_pmu(unit: str) -> Optional[str]:
      """Convert a JSON Unit to Linux PMU name."""
      if not unit:
        return 'default_core'
      # Comment brought over from jevents.c:
      # it's not realistic to keep adding these, we need something more scalable ...
      table = {
          'CBO': 'uncore_cbox',
          'QPI LL': 'uncore_qpi',
          'SBO': 'uncore_sbox',
          'iMPH-U': 'uncore_arb',
          'CPU-M-CF': 'cpum_cf',
          'CPU-M-SF': 'cpum_sf',
          'PAI-CRYPTO' : 'pai_crypto',
          'PAI-EXT' : 'pai_ext',
          'UPI LL': 'uncore_upi',
          'hisi_sicl,cpa': 'hisi_sicl,cpa',
          'hisi_sccl,ddrc': 'hisi_sccl,ddrc',
          'hisi_sccl,hha': 'hisi_sccl,hha',
          'hisi_sccl,l3c': 'hisi_sccl,l3c',
          'imx8_ddr': 'imx8_ddr',
          'imx9_ddr': 'imx9_ddr',
          'L3PMC': 'amd_l3',
          'DFPMC': 'amd_df',
          'UMCPMC': 'amd_umc',
          'cpu_core': 'cpu_core',
          'cpu_atom': 'cpu_atom',
          'ali_drw': 'ali_drw',
          'arm_cmn': 'arm_cmn',
      }
      return table[unit] if unit in table else f'uncore_{unit.lower()}'

    def is_zero(val: str) -> bool:
        try:
            if val.startswith('0x'):
                return int(val, 16) == 0
            else:
                return int(val) == 0
        except e:
            return False

    def canonicalize_value(val: str) -> str:
        try:
            if val.startswith('0x'):
                return llx(int(val, 16))
            return str(int(val))
        except e:
            return val

    eventcode = 0
    if 'EventCode' in jd:
      eventcode = int(jd['EventCode'].split(',', 1)[0], 0)
    if 'ExtSel' in jd:
      eventcode |= int(jd['ExtSel']) << 8
    configcode = int(jd['ConfigCode'], 0) if 'ConfigCode' in jd else None
    eventidcode = int(jd['EventidCode'], 0) if 'EventidCode' in jd else None
    self.name = jd['EventName'].lower() if 'EventName' in jd else None
    self.topic = ''
    self.compat = jd.get('Compat')
    self.desc = fixdesc(jd.get('BriefDescription'))
    self.long_desc = fixdesc(jd.get('PublicDescription'))
    precise = jd.get('PEBS')
    msr = lookup_msr(jd.get('MSRIndex'))
    msrval = jd.get('MSRValue')
    extra_desc = ''
    if 'Data_LA' in jd:
      extra_desc += '  Supports address when precise'
      if 'Errata' in jd:
        extra_desc += '.'
    if 'Errata' in jd:
      extra_desc += '  Spec update: ' + jd['Errata']
    self.pmu = unit_to_pmu(jd.get('Unit'))
    filter = jd.get('Filter')
    self.unit = jd.get('ScaleUnit')
    self.perpkg = jd.get('PerPkg')
    self.aggr_mode = convert_aggr_mode(jd.get('AggregationMode'))
    self.deprecated = jd.get('Deprecated')
    self.metric_name = jd.get('MetricName')
    self.metric_group = jd.get('MetricGroup')
    self.metricgroup_no_group = jd.get('MetricgroupNoGroup')
    self.default_metricgroup_name = jd.get('DefaultMetricgroupName')
    self.event_grouping = convert_metric_constraint(jd.get('MetricConstraint'))
    self.metric_expr = None
    if 'MetricExpr' in jd:
      self.metric_expr = metric.ParsePerfJson(jd['MetricExpr']).Simplify()
    # Note, the metric formula for the threshold isn't parsed as the &
    # and > have incorrect precedence.
    self.metric_threshold = jd.get('MetricThreshold')

    arch_std = jd.get('ArchStdEvent')
    if precise and self.desc and '(Precise Event)' not in self.desc:
      extra_desc += ' (Must be precise)' if precise == '2' else (' (Precise '
                                                                 'event)')
    event = None
    if configcode is not None:
      event = f'config={llx(configcode)}'
    elif eventidcode is not None:
      event = f'eventid={llx(eventidcode)}'
    else:
      event = f'event={llx(eventcode)}'
    event_fields = [
        ('AnyThread', 'any='),
        ('PortMask', 'ch_mask='),
        ('CounterMask', 'cmask='),
        ('EdgeDetect', 'edge='),
        ('FCMask', 'fc_mask='),
        ('Invert', 'inv='),
        ('SampleAfterValue', 'period='),
        ('UMask', 'umask='),
        ('NodeType', 'type='),
        ('RdWrMask', 'rdwrmask='),
        ('EnAllCores', 'enallcores='),
        ('EnAllSlices', 'enallslices='),
        ('SliceId', 'sliceid='),
        ('ThreadMask', 'threadmask='),
    ]
    for key, value in event_fields:
      if key in jd and not is_zero(jd[key]):
        event += f',{value}{canonicalize_value(jd[key])}'
    if filter:
      event += f',{filter}'
    if msr:
      event += f',{msr}{msrval}'
    if self.desc and extra_desc:
      self.desc += extra_desc
    if self.long_desc and extra_desc:
      self.long_desc += extra_desc
    if arch_std:
      if arch_std.lower() in _arch_std_events:
        event = _arch_std_events[arch_std.lower()].event
        # Copy from the architecture standard event to self for undefined fields.
        for attr, value in _arch_std_events[arch_std.lower()].__dict__.items():
          if hasattr(self, attr) and not getattr(self, attr):
            setattr(self, attr, value)
      else:
        raise argparse.ArgumentTypeError('Cannot find arch std event:', arch_std)

    self.event = real_event(self.name, event)

  def __repr__(self) -> str:
    """String representation primarily for debugging."""
    s = '{\n'
    for attr, value in self.__dict__.items():
      if value:
        s += f'\t{attr} = {value},\n'
    return s + '}'

  def build_c_string(self, metric: bool) -> str:
    s = ''
    for attr in _json_metric_attributes if metric else _json_event_attributes:
      x = getattr(self, attr)
      if metric and x and attr == 'metric_expr':
        # Convert parsed metric expressions into a string. Slashes
        # must be doubled in the file.
        x = x.ToPerfJson().replace('\\', '\\\\')
      if metric and x and attr == 'metric_threshold':
        x = x.replace('\\', '\\\\')
      if attr in _json_enum_attributes:
        s += x if x else '0'
      else:
        s += f'{x}\\000' if x else '\\000'
    return s

  def to_c_string(self, metric: bool) -> str:
    """Representation of the event as a C struct initializer."""

    s = self.build_c_string(metric)
    return f'{{ { _bcs.offsets[s] } }}, /* {s} */\n'


@lru_cache(maxsize=None)
def read_json_events(path: str, topic: str) -> Sequence[JsonEvent]:
  """Read json events from the specified file."""
  try:
    events = json.load(open(path), object_hook=JsonEvent)
  except BaseException as err:
    print(f"Exception processing {path}")
    raise
  metrics: list[Tuple[str, str, metric.Expression]] = []
  for event in events:
    event.topic = topic
    if event.metric_name and '-' not in event.metric_name:
      metrics.append((event.pmu, event.metric_name, event.metric_expr))
  updates = metric.RewriteMetricsInTermsOfOthers(metrics)
  if updates:
    for event in events:
      if event.metric_name in updates:
        # print(f'Updated {event.metric_name} from\n"{event.metric_expr}"\n'
        #       f'to\n"{updates[event.metric_name]}"')
        event.metric_expr = updates[event.metric_name]

  return events

def preprocess_arch_std_files(archpath: str) -> None:
  """Read in all architecture standard events."""
  global _arch_std_events
  for item in os.scandir(archpath):
    if item.is_file() and item.name.endswith('.json'):
      for event in read_json_events(item.path, topic=''):
        if event.name:
          _arch_std_events[event.name.lower()] = event
        if event.metric_name:
          _arch_std_events[event.metric_name.lower()] = event


def add_events_table_entries(item: os.DirEntry, topic: str) -> None:
  """Add contents of file to _pending_events table."""
  for e in read_json_events(item.path, topic):
    if e.name:
      _pending_events.append(e)
    if e.metric_name:
      _pending_metrics.append(e)


def print_pending_events() -> None:
  """Optionally close events table."""

  def event_cmp_key(j: JsonEvent) -> Tuple[str, str, bool, str, str]:
    def fix_none(s: Optional[str]) -> str:
      if s is None:
        return ''
      return s

    return (fix_none(j.pmu).replace(',','_'), fix_none(j.name), j.desc is not None, fix_none(j.topic),
            fix_none(j.metric_name))

  global _pending_events
  if not _pending_events:
    return

  global _pending_events_tblname
  if _pending_events_tblname.endswith('_sys'):
    global _sys_event_tables
    _sys_event_tables.append(_pending_events_tblname)
  else:
    global event_tables
    _event_tables.append(_pending_events_tblname)

  first = True
  last_pmu = None
  pmus = set()
  for event in sorted(_pending_events, key=event_cmp_key):
    if event.pmu != last_pmu:
      if not first:
        _args.output_file.write('};\n')
      pmu_name = event.pmu.replace(',', '_')
      _args.output_file.write(
          f'static const struct compact_pmu_event {_pending_events_tblname}_{pmu_name}[] = {{\n')
      first = False
      last_pmu = event.pmu
      pmus.add((event.pmu, pmu_name))

    _args.output_file.write(event.to_c_string(metric=False))
  _pending_events = []

  _args.output_file.write(f"""
}};

const struct pmu_table_entry {_pending_events_tblname}[] = {{
""")
  for (pmu, tbl_pmu) in sorted(pmus):
    pmu_name = f"{pmu}\\000"
    _args.output_file.write(f"""{{
     .entries = {_pending_events_tblname}_{tbl_pmu},
     .num_entries = ARRAY_SIZE({_pending_events_tblname}_{tbl_pmu}),
     .pmu_name = {{ {_bcs.offsets[pmu_name]} /* {pmu_name} */ }},
}},
""")
  _args.output_file.write('};\n\n')

def print_pending_metrics() -> None:
  """Optionally close metrics table."""

  def metric_cmp_key(j: JsonEvent) -> Tuple[bool, str, str]:
    def fix_none(s: Optional[str]) -> str:
      if s is None:
        return ''
      return s

    return (j.desc is not None, fix_none(j.pmu), fix_none(j.metric_name))

  global _pending_metrics
  if not _pending_metrics:
    return

  global _pending_metrics_tblname
  if _pending_metrics_tblname.endswith('_sys'):
    global _sys_metric_tables
    _sys_metric_tables.append(_pending_metrics_tblname)
  else:
    global metric_tables
    _metric_tables.append(_pending_metrics_tblname)

  first = True
  last_pmu = None
  pmus = set()
  for metric in sorted(_pending_metrics, key=metric_cmp_key):
    if metric.pmu != last_pmu:
      if not first:
        _args.output_file.write('};\n')
      pmu_name = metric.pmu.replace(',', '_')
      _args.output_file.write(
          f'static const struct compact_pmu_event {_pending_metrics_tblname}_{pmu_name}[] = {{\n')
      first = False
      last_pmu = metric.pmu
      pmus.add((metric.pmu, pmu_name))

    _args.output_file.write(metric.to_c_string(metric=True))
  _pending_metrics = []

  _args.output_file.write(f"""
}};

const struct pmu_table_entry {_pending_metrics_tblname}[] = {{
""")
  for (pmu, tbl_pmu) in sorted(pmus):
    pmu_name = f"{pmu}\\000"
    _args.output_file.write(f"""{{
     .entries = {_pending_metrics_tblname}_{tbl_pmu},
     .num_entries = ARRAY_SIZE({_pending_metrics_tblname}_{tbl_pmu}),
     .pmu_name = {{ {_bcs.offsets[pmu_name]} /* {pmu_name} */ }},
}},
""")
  _args.output_file.write('};\n\n')

def get_topic(topic: str) -> str:
  if topic.endswith('metrics.json'):
    return 'metrics'
  return removesuffix(topic, '.json').replace('-', ' ')

def preprocess_one_file(parents: Sequence[str], item: os.DirEntry) -> None:

  if item.is_dir():
    return

  # base dir or too deep
  level = len(parents)
  if level == 0 or level > 4:
    return

  # Ignore other directories. If the file name does not have a .json
  # extension, ignore it. It could be a readme.txt for instance.
  if not item.is_file() or not item.name.endswith('.json'):
    return

  if item.name == 'metricgroups.json':
    metricgroup_descriptions = json.load(open(item.path))
    for mgroup in metricgroup_descriptions:
      assert len(mgroup) > 1, parents
      description = f"{metricgroup_descriptions[mgroup]}\\000"
      mgroup = f"{mgroup}\\000"
      _bcs.add(mgroup, metric=True)
      _bcs.add(description, metric=True)
      _metricgroups[mgroup] = description
    return

  topic = get_topic(item.name)
  for event in read_json_events(item.path, topic):
    pmu_name = f"{event.pmu}\\000"
    if event.name:
      _bcs.add(pmu_name, metric=False)
      _bcs.add(event.build_c_string(metric=False), metric=False)
    if event.metric_name:
      _bcs.add(pmu_name, metric=True)
      _bcs.add(event.build_c_string(metric=True), metric=True)

def process_one_file(parents: Sequence[str], item: os.DirEntry) -> None:
  """Process a JSON file during the main walk."""
  def is_leaf_dir(path: str) -> bool:
    for item in os.scandir(path):
      if item.is_dir():
        return False
    return True

  # model directory, reset topic
  if item.is_dir() and is_leaf_dir(item.path):
    print_pending_events()
    print_pending_metrics()

    global _pending_events_tblname
    _pending_events_tblname = file_name_to_table_name('pmu_events_', parents, item.name)
    global _pending_metrics_tblname
    _pending_metrics_tblname = file_name_to_table_name('pmu_metrics_', parents, item.name)

    if item.name == 'sys':
      _sys_event_table_to_metric_table_mapping[_pending_events_tblname] = _pending_metrics_tblname
    return

  # base dir or too deep
  level = len(parents)
  if level == 0 or level > 4:
    return

  # Ignore other directories. If the file name does not have a .json
  # extension, ignore it. It could be a readme.txt for instance.
  if not item.is_file() or not item.name.endswith('.json') or item.name == 'metricgroups.json':
    return

  add_events_table_entries(item, get_topic(item.name))


def print_mapping_table(archs: Sequence[str]) -> None:
  """Read the mapfile and generate the struct from cpuid string to event table."""
  _args.output_file.write("""
/* Struct used to make the PMU event table implementation opaque to callers. */
struct pmu_events_table {
        const struct pmu_table_entry *pmus;
        uint32_t num_pmus;
};

/* Struct used to make the PMU metric table implementation opaque to callers. */
struct pmu_metrics_table {
        const struct pmu_table_entry *pmus;
        uint32_t num_pmus;
};

/*
 * Map a CPU to its table of PMU events. The CPU is identified by the
 * cpuid field, which is an arch-specific identifier for the CPU.
 * The identifier specified in tools/perf/pmu-events/arch/xxx/mapfile
 * must match the get_cpuid_str() in tools/perf/arch/xxx/util/header.c)
 *
 * The  cpuid can contain any character other than the comma.
 */
struct pmu_events_map {
        const char *arch;
        const char *cpuid;
        struct pmu_events_table event_table;
        struct pmu_metrics_table metric_table;
};

/*
 * Global table mapping each known CPU for the architecture to its
 * table of PMU events.
 */
const struct pmu_events_map pmu_events_map[] = {
""")
  for arch in archs:
    if arch == 'test':
      _args.output_file.write("""{
\t.arch = "testarch",
\t.cpuid = "testcpu",
\t.event_table = {
\t\t.pmus = pmu_events__test_soc_cpu,
\t\t.num_pmus = ARRAY_SIZE(pmu_events__test_soc_cpu),
\t},
\t.metric_table = {
\t\t.pmus = pmu_metrics__test_soc_cpu,
\t\t.num_pmus = ARRAY_SIZE(pmu_metrics__test_soc_cpu),
\t}
},
""")
    else:
      with open(f'{_args.starting_dir}/{arch}/mapfile.csv') as csvfile:
        table = csv.reader(csvfile)
        first = True
        for row in table:
          # Skip the first row or any row beginning with #.
          if not first and len(row) > 0 and not row[0].startswith('#'):
            event_tblname = file_name_to_table_name('pmu_events_', [], row[2].replace('/', '_'))
            if event_tblname in _event_tables:
              event_size = f'ARRAY_SIZE({event_tblname})'
            else:
              event_tblname = 'NULL'
              event_size = '0'
            metric_tblname = file_name_to_table_name('pmu_metrics_', [], row[2].replace('/', '_'))
            if metric_tblname in _metric_tables:
              metric_size = f'ARRAY_SIZE({metric_tblname})'
            else:
              metric_tblname = 'NULL'
              metric_size = '0'
            if event_size == '0' and metric_size == '0':
              continue
            cpuid = row[0].replace('\\', '\\\\')
            _args.output_file.write(f"""{{
\t.arch = "{arch}",
\t.cpuid = "{cpuid}",
\t.event_table = {{
\t\t.pmus = {event_tblname},
\t\t.num_pmus = {event_size}
\t}},
\t.metric_table = {{
\t\t.pmus = {metric_tblname},
\t\t.num_pmus = {metric_size}
\t}}
}},
""")
          first = False

  _args.output_file.write("""{
\t.arch = 0,
\t.cpuid = 0,
\t.event_table = { 0, 0 },
\t.metric_table = { 0, 0 },
}
};
""")


def print_system_mapping_table() -> None:
  """C struct mapping table array for tables from /sys directories."""
  _args.output_file.write("""
struct pmu_sys_events {
\tconst char *name;
\tstruct pmu_events_table event_table;
\tstruct pmu_metrics_table metric_table;
};

static const struct pmu_sys_events pmu_sys_event_tables[] = {
""")
  printed_metric_tables = []
  for tblname in _sys_event_tables:
    _args.output_file.write(f"""\t{{
\t\t.event_table = {{
\t\t\t.pmus = {tblname},
\t\t\t.num_pmus = ARRAY_SIZE({tblname})
\t\t}},""")
    metric_tblname = _sys_event_table_to_metric_table_mapping[tblname]
    if metric_tblname in _sys_metric_tables:
      _args.output_file.write(f"""
\t\t.metric_table = {{
\t\t\t.pmus = {metric_tblname},
\t\t\t.num_pmus = ARRAY_SIZE({metric_tblname})
\t\t}},""")
      printed_metric_tables.append(metric_tblname)
    _args.output_file.write(f"""
\t\t.name = \"{tblname}\",
\t}},
""")
  for tblname in _sys_metric_tables:
    if tblname in printed_metric_tables:
      continue
    _args.output_file.write(f"""\t{{
\t\t.metric_table = {{
\t\t\t.pmus = {tblname},
\t\t\t.num_pmus = ARRAY_SIZE({tblname})
\t\t}},
\t\t.name = \"{tblname}\",
\t}},
""")
  _args.output_file.write("""\t{
\t\t.event_table = { 0, 0 },
\t\t.metric_table = { 0, 0 },
\t},
};

static void decompress_event(int offset, struct pmu_event *pe)
{
\tconst char *p = &big_c_string[offset];
""")
  for attr in _json_event_attributes:
    _args.output_file.write(f'\n\tpe->{attr} = ')
    if attr in _json_enum_attributes:
      _args.output_file.write("*p - '0';\n")
    else:
      _args.output_file.write("(*p == '\\0' ? NULL : p);\n")
    if attr == _json_event_attributes[-1]:
      continue
    if attr in _json_enum_attributes:
      _args.output_file.write('\tp++;')
    else:
      _args.output_file.write('\twhile (*p++);')
  _args.output_file.write("""}

static void decompress_metric(int offset, struct pmu_metric *pm)
{
\tconst char *p = &big_c_string[offset];
""")
  for attr in _json_metric_attributes:
    _args.output_file.write(f'\n\tpm->{attr} = ')
    if attr in _json_enum_attributes:
      _args.output_file.write("*p - '0';\n")
    else:
      _args.output_file.write("(*p == '\\0' ? NULL : p);\n")
    if attr == _json_metric_attributes[-1]:
      continue
    if attr in _json_enum_attributes:
      _args.output_file.write('\tp++;')
    else:
      _args.output_file.write('\twhile (*p++);')
  _args.output_file.write("""}

static int pmu_events_table__for_each_event_pmu(const struct pmu_events_table *table,
                                                const struct pmu_table_entry *pmu,
                                                pmu_event_iter_fn fn,
                                                void *data)
{
        int ret;
        struct pmu_event pe = {
                .pmu = &big_c_string[pmu->pmu_name.offset],
        };

        for (uint32_t i = 0; i < pmu->num_entries; i++) {
                decompress_event(pmu->entries[i].offset, &pe);
                if (!pe.name)
                        continue;
                ret = fn(&pe, table, data);
                if (ret)
                        return ret;
        }
        return 0;
 }

static int pmu_events_table__find_event_pmu(const struct pmu_events_table *table,
                                            const struct pmu_table_entry *pmu,
                                            const char *name,
                                            pmu_event_iter_fn fn,
                                            void *data)
{
        struct pmu_event pe = {
                .pmu = &big_c_string[pmu->pmu_name.offset],
        };
        int low = 0, high = pmu->num_entries - 1;

        while (low <= high) {
                int cmp, mid = (low + high) / 2;

                decompress_event(pmu->entries[mid].offset, &pe);

                if (!pe.name && !name)
                        goto do_call;

                if (!pe.name && name) {
                        low = mid + 1;
                        continue;
                }
                if (pe.name && !name) {
                        high = mid - 1;
                        continue;
                }

                cmp = strcasecmp(pe.name, name);
                if (cmp < 0) {
                        low = mid + 1;
                        continue;
                }
                if (cmp > 0) {
                        high = mid - 1;
                        continue;
                }
  do_call:
                return fn ? fn(&pe, table, data) : 0;
        }
        return -1000;
}

int pmu_events_table__for_each_event(const struct pmu_events_table *table,
                                    struct perf_pmu *pmu,
                                    pmu_event_iter_fn fn,
                                    void *data)
{
        for (size_t i = 0; i < table->num_pmus; i++) {
                const struct pmu_table_entry *table_pmu = &table->pmus[i];
                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
                int ret;

                if (pmu && !pmu__name_match(pmu, pmu_name))
                        continue;

                ret = pmu_events_table__for_each_event_pmu(table, table_pmu, fn, data);
                if (pmu || ret)
                        return ret;
        }
        return 0;
}

int pmu_events_table__find_event(const struct pmu_events_table *table,
                                 struct perf_pmu *pmu,
                                 const char *name,
                                 pmu_event_iter_fn fn,
                                 void *data)
{
        for (size_t i = 0; i < table->num_pmus; i++) {
                const struct pmu_table_entry *table_pmu = &table->pmus[i];
                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];
                int ret;

                if (!pmu__name_match(pmu, pmu_name))
                        continue;

                ret = pmu_events_table__find_event_pmu(table, table_pmu, name, fn, data);
                if (ret != -1000)
                        return ret;
        }
        return -1000;
}

size_t pmu_events_table__num_events(const struct pmu_events_table *table,
                                    struct perf_pmu *pmu)
{
        size_t count = 0;

        for (size_t i = 0; i < table->num_pmus; i++) {
                const struct pmu_table_entry *table_pmu = &table->pmus[i];
                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];

                if (pmu__name_match(pmu, pmu_name))
                        count += table_pmu->num_entries;
        }
        return count;
}

static int pmu_metrics_table__for_each_metric_pmu(const struct pmu_metrics_table *table,
                                                const struct pmu_table_entry *pmu,
                                                pmu_metric_iter_fn fn,
                                                void *data)
{
        int ret;
        struct pmu_metric pm = {
                .pmu = &big_c_string[pmu->pmu_name.offset],
        };

        for (uint32_t i = 0; i < pmu->num_entries; i++) {
                decompress_metric(pmu->entries[i].offset, &pm);
                if (!pm.metric_expr)
                        continue;
                ret = fn(&pm, table, data);
                if (ret)
                        return ret;
        }
        return 0;
}

int pmu_metrics_table__for_each_metric(const struct pmu_metrics_table *table,
                                     pmu_metric_iter_fn fn,
                                     void *data)
{
        for (size_t i = 0; i < table->num_pmus; i++) {
                int ret = pmu_metrics_table__for_each_metric_pmu(table, &table->pmus[i],
                                                                 fn, data);

                if (ret)
                        return ret;
        }
        return 0;
}

static const struct pmu_events_map *map_for_pmu(struct perf_pmu *pmu)
{
        static struct {
                const struct pmu_events_map *map;
                struct perf_pmu *pmu;
        } last_result;
        static struct {
                const struct pmu_events_map *map;
                char *cpuid;
        } last_map_search;
        static bool has_last_result, has_last_map_search;
        const struct pmu_events_map *map = NULL;
        char *cpuid = NULL;
        size_t i;

        if (has_last_result && last_result.pmu == pmu)
                return last_result.map;

        cpuid = perf_pmu__getcpuid(pmu);

        /*
         * On some platforms which uses cpus map, cpuid can be NULL for
         * PMUs other than CORE PMUs.
         */
        if (!cpuid)
                goto out_update_last_result;

        if (has_last_map_search && !strcmp(last_map_search.cpuid, cpuid)) {
                map = last_map_search.map;
                free(cpuid);
        } else {
                i = 0;
                for (;;) {
                        map = &pmu_events_map[i++];

                        if (!map->arch) {
                                map = NULL;
                                break;
                        }

                        if (!strcmp_cpuid_str(map->cpuid, cpuid))
                                break;
               }
               free(last_map_search.cpuid);
               last_map_search.cpuid = cpuid;
               last_map_search.map = map;
               has_last_map_search = true;
        }
out_update_last_result:
        last_result.pmu = pmu;
        last_result.map = map;
        has_last_result = true;
        return map;
}

const struct pmu_events_table *perf_pmu__find_events_table(struct perf_pmu *pmu)
{
        const struct pmu_events_map *map = map_for_pmu(pmu);

        if (!map)
                return NULL;

        if (!pmu)
                return &map->event_table;

        for (size_t i = 0; i < map->event_table.num_pmus; i++) {
                const struct pmu_table_entry *table_pmu = &map->event_table.pmus[i];
                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];

                if (pmu__name_match(pmu, pmu_name))
                         return &map->event_table;
        }
        return NULL;
}

const struct pmu_metrics_table *perf_pmu__find_metrics_table(struct perf_pmu *pmu)
{
        const struct pmu_events_map *map = map_for_pmu(pmu);

        if (!map)
                return NULL;

        if (!pmu)
                return &map->metric_table;

        for (size_t i = 0; i < map->metric_table.num_pmus; i++) {
                const struct pmu_table_entry *table_pmu = &map->metric_table.pmus[i];
                const char *pmu_name = &big_c_string[table_pmu->pmu_name.offset];

                if (pmu__name_match(pmu, pmu_name))
                           return &map->metric_table;
        }
        return NULL;
}

const struct pmu_events_table *find_core_events_table(const char *arch, const char *cpuid)
{
        for (const struct pmu_events_map *tables = &pmu_events_map[0];
             tables->arch;
             tables++) {
                if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
                        return &tables->event_table;
        }
        return NULL;
}

const struct pmu_metrics_table *find_core_metrics_table(const char *arch, const char *cpuid)
{
        for (const struct pmu_events_map *tables = &pmu_events_map[0];
             tables->arch;
             tables++) {
                if (!strcmp(tables->arch, arch) && !strcmp_cpuid_str(tables->cpuid, cpuid))
                        return &tables->metric_table;
        }
        return NULL;
}

int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
{
        for (const struct pmu_events_map *tables = &pmu_events_map[0];
             tables->arch;
             tables++) {
                int ret = pmu_events_table__for_each_event(&tables->event_table,
                                                           /*pmu=*/ NULL, fn, data);

                if (ret)
                        return ret;
        }
        return 0;
}

int pmu_for_each_core_metric(pmu_metric_iter_fn fn, void *data)
{
        for (const struct pmu_events_map *tables = &pmu_events_map[0];
             tables->arch;
             tables++) {
                int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data);

                if (ret)
                        return ret;
        }
        return 0;
}

const struct pmu_events_table *find_sys_events_table(const char *name)
{
        for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
             tables->name;
             tables++) {
                if (!strcmp(tables->name, name))
                        return &tables->event_table;
        }
        return NULL;
}

int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
{
        for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
             tables->name;
             tables++) {
                int ret = pmu_events_table__for_each_event(&tables->event_table,
                                                           /*pmu=*/ NULL, fn, data);

                if (ret)
                        return ret;
        }
        return 0;
}

int pmu_for_each_sys_metric(pmu_metric_iter_fn fn, void *data)
{
        for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
             tables->name;
             tables++) {
                int ret = pmu_metrics_table__for_each_metric(&tables->metric_table, fn, data);

                if (ret)
                        return ret;
        }
        return 0;
}
""")

def print_metricgroups() -> None:
  _args.output_file.write("""
static const int metricgroups[][2] = {
""")
  for mgroup in sorted(_metricgroups):
    description = _metricgroups[mgroup]
    _args.output_file.write(
        f'\t{{ {_bcs.offsets[mgroup]}, {_bcs.offsets[description]} }}, /* {mgroup} => {description} */\n'
    )
  _args.output_file.write("""
};

const char *describe_metricgroup(const char *group)
{
        int low = 0, high = (int)ARRAY_SIZE(metricgroups) - 1;

        while (low <= high) {
                int mid = (low + high) / 2;
                const char *mgroup = &big_c_string[metricgroups[mid][0]];
                int cmp = strcmp(mgroup, group);

                if (cmp == 0) {
                        return &big_c_string[metricgroups[mid][1]];
                } else if (cmp < 0) {
                        low = mid + 1;
                } else {
                        high = mid - 1;
                }
        }
        return NULL;
}
""")

def main() -> None:
  global _args

  def dir_path(path: str) -> str:
    """Validate path is a directory for argparse."""
    if os.path.isdir(path):
      return path
    raise argparse.ArgumentTypeError(f'\'{path}\' is not a valid directory')

  def ftw(path: str, parents: Sequence[str],
          action: Callable[[Sequence[str], os.DirEntry], None]) -> None:
    """Replicate the directory/file walking behavior of C's file tree walk."""
    for item in sorted(os.scandir(path), key=lambda e: e.name):
      if _args.model != 'all' and item.is_dir():
        # Check if the model matches one in _args.model.
        if len(parents) == _args.model.split(',')[0].count('/'):
          # We're testing the correct directory.
          item_path = '/'.join(parents) + ('/' if len(parents) > 0 else '') + item.name
          if 'test' not in item_path and item_path not in _args.model.split(','):
            continue
      action(parents, item)
      if item.is_dir():
        ftw(item.path, parents + [item.name], action)

  ap = argparse.ArgumentParser()
  ap.add_argument('arch', help='Architecture name like x86')
  ap.add_argument('model', help='''Select a model such as skylake to
reduce the code size.  Normally set to "all". For architectures like
ARM64 with an implementor/model, the model must include the implementor
such as "arm/cortex-a34".''',
                  default='all')
  ap.add_argument(
      'starting_dir',
      type=dir_path,
      help='Root of tree containing architecture directories containing json files'
  )
  ap.add_argument(
      'output_file', type=argparse.FileType('w', encoding='utf-8'), nargs='?', default=sys.stdout)
  _args = ap.parse_args()

  _args.output_file.write("""
#include <pmu-events/pmu-events.h>
#include "util/header.h"
#include "util/pmu.h"
#include <string.h>
#include <stddef.h>

struct compact_pmu_event {
        int offset;
};

struct pmu_table_entry {
        const struct compact_pmu_event *entries;
        uint32_t num_entries;
        struct compact_pmu_event pmu_name;
};

""")
  archs = []
  for item in os.scandir(_args.starting_dir):
    if not item.is_dir():
      continue
    if item.name == _args.arch or _args.arch == 'all' or item.name == 'test':
      archs.append(item.name)

  if len(archs) < 2:
    raise IOError(f'Missing architecture directory \'{_args.arch}\'')

  archs.sort()
  for arch in archs:
    arch_path = f'{_args.starting_dir}/{arch}'
    preprocess_arch_std_files(arch_path)
    ftw(arch_path, [], preprocess_one_file)

  _bcs.compute()
  _args.output_file.write('static const char *const big_c_string =\n')
  for s in _bcs.big_string:
    _args.output_file.write(s)
  _args.output_file.write(';\n\n')
  for arch in archs:
    arch_path = f'{_args.starting_dir}/{arch}'
    ftw(arch_path, [], process_one_file)
    print_pending_events()
    print_pending_metrics()

  print_mapping_table(archs)
  print_system_mapping_table()
  print_metricgroups()

if __name__ == '__main__':
  main()
