# frozen_string_literal: true

require 'bunny'

module OpenTracing
  module Instrumentation
    module Bunny
      # PublishTagsBuilder build span tags for Bunny::PublishTracer
      class PublishTagsBuilder
        DEFAULT_STATIC_TAGS = {
          'span.kind' => 'publiser',
          'component' => 'bunny',
        }.freeze

        DEFAULT_CONTENT_TYPE = ::Bunny::Channel::DEFAULT_CONTENT_TYPE
        DEFAULT_PERSISTENT = true
        DEFAAUL_PRIORITY = 0

        # @param static_tags [Hash<String, String>]
        def initialize(static_tags: DEFAULT_STATIC_TAGS)
          @static_tags = static_tags
        end

        # @param exchange [Bunny::Exchange]
        # @param opts [Hash<>]
        # @option opts [String, nil] :routing_key
        # @option opts [String, nil] :content_type
        # @option opts [String, nil] :message_id
        # @option opts [Integer, nil] :expiration
        # @option opts [String, nil] :content_encoding
        # @option opts [Boolean, nil] :persistent
        # @option opts [Boolean, nil] :mandatory
        # @option opts [Integer, nil] :priority
        # @option opts [String, nil] :app_id
        # @return [Hash<String, String>]
        def build_tags(exchange, opts)
          @static_tags
            .merge(exchange_tags(exchange))
            .merge(meta_tags(opts))
            .merge(extended_tags(opts))
            .compact
        end

        private

        def exchange_tags(exchange)
          {
            'amqp.exchange' => exchange.name,
            'amqp.exchange_type' => exchange.type,
          }
        end

        def meta_tags(opts)
          content_type = opts.fetch(:content_type, DEFAULT_CONTENT_TYPE)
          {
            'amqp.routing_key' => opts[:routing_key],
            'amqp.content_type' => content_type,
            'amqp.message_id' => opts[:message_id],
            'amqp.expiration' => opts[:expiration],
            'amqp.content_encoding' => opts[:content_encoding],
          }
        end

        def extended_tags(opts)
          persistent = opts.fetch(:persistent, DEFAULT_PERSISTENT)
          priority = opts.fetch(:priority, DEFAAUL_PRIORITY)

          {
            'amqp.persistent' => persistent,
            'amqp.mandatory' => opts[:mandatory],
            'amqp.priority' => priority,
            'amqp.app_id' => opts[:app_id],
          }
        end
      end
    end
  end
end