if defined? Prometheus
  module Prometheus
    require "zuora_connect/version"
    require "zuora_api/version"

    resque_path = "#{ENV['RESQUE_EXPORTER_PATH'] || Rails.root.join('tmp/resque_exporter')}/*.prom"
    prometheus_path = Rails.root.join("tmp/prometheus")

    Dir[resque_path, "#{prometheus_path}/*.bin"].each do |file_path|
      File.unlink(file_path)
    end

    require 'prometheus/client/data_stores/direct_file_store'
    Prometheus::Client.config.data_store = Prometheus::Client::DataStores::DirectFileStore.new(
      dir: prometheus_path
    )

    class ResqueExporter
      require 'prometheus/client/formats/text'
      require 'fileutils'

      def initialize
        @lock = Monitor.new
        @registry = Prometheus::Client.registry
        @path = ENV['RESQUE_EXPORTER_PATH'] || Rails.root.join('tmp/resque_exporter')
        FileUtils.mkdir_p(@path)
      end

      def export
        filename = File.join(@path, 'resque_export.prom')
        @lock.synchronize do
          File.open(filename, 'w+') do |file|
            file.write(Prometheus::Client::Formats::Text.marshal(@registry))
          end
        end
      rescue
        # Ignored
      end
    end

    most_recent_aggregation = {}
    sum_aggregation = {}
    if defined?(Unicorn)
      most_recent_aggregation[:aggregation] = :most_recent
      sum_aggregation[:aggregation] = :sum
    end

    # Create a default Prometheus registry for our metrics.
    prometheus = Prometheus::Client.registry

    # Create your metrics.
    ZUORA_VERSION = prometheus.gauge(:zuora_version, docstring: 'The current Zuora Gem version.', labels: %i(version name),  preset_labels: { version: ZuoraAPI::VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
    CONNECT_VERSION = prometheus.gauge(:gem_version, docstring: 'The current Connect Gem version.', labels: %i(version name), preset_labels: { version: ZuoraConnect::VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
    RAILS_VERSION = prometheus.gauge(:rails_version, docstring: 'The current Rails version.', labels: %i(version name), preset_labels: { version: Rails.version, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
    RUBY_V = prometheus.gauge(:ruby_version, docstring: 'The current Ruby version.', labels: %i(version name), preset_labels: { version: RUBY_VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)

    ZUORA_VERSION.set(0)
    CONNECT_VERSION.set(0)
    RAILS_VERSION.set(0)
    RUBY_V.set(0)

    # Do they have resque jobs?
    if defined? Resque.redis
      REDIS_CONNECTION = prometheus.gauge(:redis_connection, docstring: 'The status of the redis connection, 0 or 1', labels: %i(connection name), preset_labels: {connection:'redis', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
      JOBS_FINISHED = prometheus.gauge(:jobs_finished, docstring: 'Done resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
      WORKERS_TOTAL = prometheus.gauge(:workers_total, docstring: 'Total resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
      WORKERS_ACTIVE = prometheus.gauge(:workers_active, docstring: 'Active resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
      JOBS_FAILED = prometheus.gauge(:jobs_failed, docstring: 'Failed resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
      JOBS_PENDING = prometheus.gauge(:jobs_pending, docstring: 'Pending resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
    end

    if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
      UNICORN_KILLS = prometheus.gauge(
        :unicorn_kills,
        docstring: 'Unicorn Kills',
        labels: %i(type name),
        preset_labels: {type:'Unicorn-Killer', name: ZuoraConnect::Telegraf.app_name},
        store_settings: sum_aggregation
      )

      ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, _|
        gauge_name = "unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_')
        gauge = prometheus.gauge(
          gauge_name.to_sym,
          docstring: 'Unicorn Stats',
          labels: %i(type name),
          preset_labels: { type: 'unicorn', name: ZuoraConnect::Telegraf.app_name },
          store_settings: most_recent_aggregation
        )
        Prometheus.const_set(
          gauge_name.upcase,
          gauge
        )
      end
    end
  end
end