{# The final Ruby code is autogenerated, but this
Jinja2 template is not. Please file bugs! #}
# 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 http://mozilla.org/MPL/2.0/.

# AUTOGENERATED BY glean_parser v{{ parser_version }}. DO NOT EDIT.

# frozen_string_literal: true

# requires json, securerandom, and logger libs
require 'json'
require 'securerandom'
require 'logger'

# this will be used for identifying logs that need to forward to Moz Data Pipeline
GLEAN_EVENT_MOZLOG_TYPE = 'glean-server-event'

module Glean
{% for ping, metrics_by_type in pings.items() %}
  class {{ ping|ping_class_name }}
    def initialize(app_id:, app_display_version:, app_channel:, logger_options:)
      @app_id = app_id # string - Application Id to identify application per Glean standards
      @app_display_version = app_display_version # string - Version of application emitting the event
      @app_channel = app_channel # string - Application Id to identify application per Glean standards
      @logger = Logger.new(logger_options)

      # Logger configuration
      @logger.formatter = proc do |severity, datetime, _progname, msg|
        date_format = datetime.to_i
        logger_name = 'glean'
        "#{JSON.dump(Timestamp: date_format.to_s, Logger: logger_name.to_s, Type: GLEAN_EVENT_MOZLOG_TYPE.to_s, Severity: severity.ljust(5).to_s, Pid: Process.pid.to_s, Fields: msg)}\n"
      end

      # Generated events
      {% for metric_type, metrics in metrics_by_type.items() %}
      {% for metric in metrics %}
      {% if metric.type == 'event' %}
      # {{ metric|metric_argument_description }}
      @{{ metric|metric_argument_name }} = {{ metric|event_class_name }}.new(self)
      {% endif %}
      {% endfor %}
      {% endfor %}
    end

    def _record(
      {% for metric_type, metrics in metrics_by_type.items() %}
      {% if metric_type != 'event' %}
      {% for metric in metrics %}
      # {{ metric|metric_argument_description }}
      {{ metric|metric_argument_name }}:,
      {% endfor %}
      {% endif %}
      {% endfor %}
      # full user_agent value from controller context
      user_agent:,
      # ip address value from controller context
      ip_address:,
      # event being sent in the ping
      event:
    )
      t_utc = Time.now.utc
      # create raw metrics hash that can have nil values
      metrics_raw = {
        {% for metric_type, metrics in metrics_by_type.items() %}
        {% if metric_type != 'event' %}
        '{{ metric_type }}' => {
        {% for metric in metrics %}
          '{{ metric|metric_name }}' => {{ metric|metric_argument_name }},
        {% endfor %}
        },
        {% endif %}
        {% endfor %}
      }
      # filter out key value pairs where value is nil
      metrics_raw.each do |key, value|
        metrics_raw[key] = value.compact.transform_values(&:to_s)
      end
      # filter out metrics with empty hashes
      metrics = metrics_raw.reject { |_k, v| v.empty? }
      event_payload = {
        # `Unknown` fields below are required in the Glean schema, however they are not useful in server context.
        'client_info' => {
          'telemetry_sdk_build' => 'glean_parser v{{ parser_version }}',
          'first_run_date' => 'Unknown',
          'os' => 'Unknown',
          'os_version' => 'Unknown',
          'architecture' => 'Unknown',
          'app_build' => 'Unknown',
          'app_display_version' => @app_display_version,
          'app_channel' => @app_channel,
        },
        'ping_info' => {
          'seq' => 0,
          'start_time' => t_utc,
          'end_time' => t_utc,
        },
        'metrics' => metrics,
        'events' => event,
      }
      serialized_event_payload = event_payload.to_json
      # This is the message structure that Decoder expects: https://github.com/mozilla/gcp-ingestion/pull/2400.
      ping = {
        'document_namespace' => @app_id,
        'document_type' => '{{ ping }}',
        'document_version' => '1',
        'document_id' => SecureRandom.uuid,
        'user_agent' => user_agent,
        'ip_address' => ip_address,
        'payload' => serialized_event_payload,
      }
      @logger.info(ping)
    end
    {% for metric_type, metrics in metrics_by_type.items() %}
    {% for metric in metrics %}
    {% if metric.type == 'event' %}
    attr_accessor :{{ metric|metric_argument_name }}
    {% endif %}
    {% endfor %}
    {% endfor %}
  end
{% endfor %}

{% for event in pings["events"]["event"] %}
  class {{ event|event_class_name }}
    # {{ event|metric_argument_description }}
    def initialize(glean)
      @glean = glean
    end

    def record(
      # extras to pass into event detail
      {% for extra, metadata in event.extra_keys.items() %}
      {{ extra }}:,
      {% endfor %}
      {% for ping, metric_types in pings.items() %}
      {% for metric_type, metrics in metric_types.items() %}
      {% if metric_type != 'event' %}
      {% for metric in metrics %}
      # {{ metric|metric_argument_description }}
      {{ metric|metric_argument_name }}:,
      {% endfor %}
      {% endif %}
      {% endfor %}
      {% endfor %}
      # full user_agent value from controller context
      user_agent:,
      # ip address value from controller context
      ip_address:
    )
      event = [
        {
          'category' => '{{ event.category }}',
          'name' => '{{ event.name }}',
          'timestamp' => (Time.now.utc.to_f * 1000).to_i,
          'extra' => [
            {% for extra, metadata in event.extra_keys.items() %}
            ['{{ extra }}', {{ extra }}.to_s],
            {% endfor %}
          ].to_h,
        },
      ]
      @glean._record(
        {% for ping, metric_types in pings.items() %}
        {% for metric_type, metrics in metric_types.items() %}
        {% if metric_type != 'event' %}
        {% for metric in metrics %}
        {{ metric|metric_argument_name }}: {{ metric|metric_argument_name }},
        {% endfor %}
        {% endif %}
        {% endfor %}
        {% endfor %}
        user_agent: user_agent,
        ip_address: ip_address,
        event: event
      )
    end
  end
end
{% endfor %}
