# 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 {current_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
  class GleanEventsLogger
    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
      # Event triggered by the backend to record the change in state of an object (e.g. API requests to the mozilla.social Mastodon server). In the future, we could potentially use this event to track changes in state to core Mastodon objects (e.g. accounts and posts).
      @backend_object_update = BackendObjectUpdateEvent.new(self)
    end

    def _record(
      # The user's FxA account ID, if available.
      identifiers_fxa_account_id:,
      # 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 = {{
        'string' => {{
          'identifiers.fxa_account_id' => identifiers_fxa_account_id,
        }},
      }}
      # 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' => '{current_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' => 'events',
        'document_version' => '1',
        'document_id' => SecureRandom.uuid,
        'user_agent' => user_agent,
        'ip_address' => ip_address,
        'payload' => serialized_event_payload,
      }}
      @logger.info(ping)
    end
    attr_accessor :backend_object_update
  end

  class BackendObjectUpdateEvent
    # Event triggered by the backend to record the change in state of an object (e.g. API requests to the mozilla.social Mastodon server). In the future, we could potentially use this event to track changes in state to core Mastodon objects (e.g. accounts and posts).
    def initialize(glean)
      @glean = glean
    end

    def record(
      # extras to pass into event detail
      object_type:,
      object_state:,
      linking:,
      # The user's FxA account ID, if available.
      identifiers_fxa_account_id:,
      # full user_agent value from controller context
      user_agent:,
      # ip address value from controller context
      ip_address:
    )
      event = [
        {{
          'category' => 'backend',
          'name' => 'object_update',
          'timestamp' => (Time.now.utc.to_f * 1000).to_i,
          'extra' => [
            ['object_type', object_type.to_s],
            ['object_state', object_state.to_s],
            ['linking', linking.to_s],
          ].to_h,
        }},
      ]
      @glean._record(
        identifiers_fxa_account_id: identifiers_fxa_account_id,
        user_agent: user_agent,
        ip_address: ip_address,
        event: event
      )
    end
  end
end
