// AUTOGENERATED BY toolkit/components/gecko_trace/scripts/codegen.py DO NOT EDIT.

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

#ifndef GECKO_TRACE_GENERATED_EVENTS_{{ input_hash }}_H
#define GECKO_TRACE_GENERATED_EVENTS_{{ input_hash }}_H

#include "mozilla/Maybe.h"

#include "mozilla/gecko_trace/SpanEvent.h"

{% macro cpp_type(attr) -%}
  {%- if attr.type == 'boolean' -%}
    bool
  {%- elif attr.type == 'integer' -%}
    int64_t
  {%- elif attr.type == 'string' -%}
    std::string_view
  {%- elif attr.type == 'array' -%}
    mozilla::Span<const {{ cpp_type({'type': attr["items"].type}) }}>
  {%- else -%}
   {% raise "Unsupported attribute type: %s" % attr.type %}
  {%- endif -%}
{%- endmacro -%}

{%- macro class_name(event_name) -%}
  {{ event_name | camelize }}Event
{%- endmacro -%}

{%- macro param_name(attr_key) -%}
  a{{ attr_key | camelize }}
{%- endmacro -%}

{%- macro member_name(attr_key) -%}
  m{{ attr_key | camelize }}
{%- endmacro %}

namespace mozilla::gecko_trace {

/**
 * Namespace containing auto-generated event classes for GeckoTrace.
 *
 * Each event class corresponds to a trace event definition and provides
 * a builder-pattern interface for setting attributes before emission.
 */
namespace events {

{% for event_name, event in events.items() %}
/**
 * Trace event class for "{{ event.display_name or event_name }}" events.
 *
 * {{ event.description | wordwrap(76) | indent(3, True) }}
 *
 * Generated from: {{ event.__definition_site__ }}
 *
 * Usage:
 *   mozilla::gecko_trace::events::{{ event_name | camelize }}()
       {% for attr_key, attr in event.attributes.items() %}
 *     .With{{ attr_key | camelize }}({{ attr_key }})
       {% endfor %}
 *	   .Emit();
 *
{% if event.inherits_from %}
 * Inherits from:
 {% for parent_event in event.inherits_from %}
 *   - {{ class_name(parent_event) }}
 {% endfor %}
 *
{% endif %}
 * Attributes:
 {% for attr_key, attr_def in event.attributes.items() %}
 *   - {{ attr_key }} ({{ attr_def.type }}
   {%- if attr_def.type == 'array' -%}
     <{{ attr_def.items }}>
   {% endif %}):
     {{- " " ~ attr_def.description | wordwrap(56) | indent(6) | trim }}
 {% endfor %}
 */
template <class T>
class {{ class_name(event_name) }}Base :
{%- if event.inherits_from -%}
  {%- for parent_event in event.inherits_from -%}
    {{ " public " ~ class_name(parent_event) }}Base<T> {{- ", " if not loop.last }}
  {%- endfor %}
{%- else -%}
{{ " public virtual SpanEvent" }}
{%- endif %} {
 public:
  {% for attr_key, attr in event.attributes.items() %}
  /**
   * Set the {{ attr_key }} attribute for this trace event.
   *
   * {{ attr.description | wordwrap(71) | indent(3, True) }}
   *
   * @param {{ param_name(attr_key) }} The {{ attr_key }} value
   *                     (type: {{ cpp_type(attr) }})
   * @return Reference to this event object for method chaining
   */
  T& With{{ attr_key | camelize -}}
  ({{ cpp_type(attr) }} {{ param_name(attr_key) }}) {
{% if enabled %}
    {{ member_name(attr_key) }} = mozilla::Some({{ param_name(attr_key) }});
{% endif %}
    return static_cast<T&>(*this);
  }
  {% endfor %}

  bool ForEachKeyValue(
      std::function<bool(std::string_view, AttributeValue)> aCallback)
      const override {
{% if enabled %}
    {% if event.inherits_from %}
    // Process attributes from parent classes first
    {% for parent_event in event.inherits_from %}
    if (!{{ class_name(parent_event) }}Base<T>::ForEachKeyValue(aCallback)) {
      return false;
    }
    {% endfor %}

    {% endif %}
    // Process this event's attributes
    {% if event.attributes|length > 1 %}
    {% for attr_key, attr_def in event.attributes.items() %}
    if ({{ member_name(attr_key) }}.isSome() &&
        !aCallback("{{ attr_key }}",
                   AttributeValue({{ member_name(attr_key) }}.value()))) {
      return false;
    }
    {% endfor %}

    return true;
    {% else %}
    return !(({{ member_name(event.attributes | first) }}.isSome() &&
        !aCallback("{{ event.attributes | first }}",
                   AttributeValue(
                       {{- member_name(event.attributes | first ) -}}
                       .value()))));
    {% endif %}
{% else %}
    return true;
{% endif %}
  }

  std::string_view GetEventName() const override {
    return "{{ event_name }}";
  }

  size_t Size() const override {
{% if enabled %}
    size_t size = {{ event.attributes | length }};
    {% for parent_event in event.inherits_from %}
    size += {{ class_name(parent_event) }}Base<T>::Size();
    {% endfor %}
    return size;
{% else %}
    return 0;
{% endif %}
  }
{% if enabled %}

 private:
  {% for attr_key, attr_def in event.attributes.items() %}
  mozilla::Maybe<{{ cpp_type(attr_def) }}> {{ member_name(attr_key) }};
  {% endfor %}
{% endif %}
};

class {{ class_name(event_name) }} : public
{{- " " ~ class_name(event_name) }}Base<{{ class_name(event_name) }}> { };

{% endfor %}
}  // namespace events

/**
 * Namespace containing factory functions for creating trace events.
 *
 * These functions provide a convenient way to create event objects using
 * the builder pattern. Each function returns an event object that can be
 * configured with attributes and then emitted.
 *
 * Example usage:
 *   mozilla::gecko_trace::events::SomeEvent()
 *     .WithAttribute1(value1)
 *     .WithAttribute2(value2)
 *     .Emit();
 */
namespace event {

{% for event_name, event in events.items() %}
/**
 * Create a new {{ event.display_name or event_name }} trace event.
 *
 * {{ event.description | wordwrap(71) | indent(1, True) }}
 *
 * @return A new {{ class_name(event_name) }} instance ready for
 *         configuration
 */
inline events::{{ class_name(event_name) }} {{ event_name | camelize }}() {
  return events::{{ class_name(event_name) }}{};
}

{% endfor %}
}  // namespace event

}  // namespace mozilla::gecko_trace

#endif  // GECKO_TRACE_GENERATED_EVENTS_{{ input_hash }}_H
