class ZuoraConnect::MetricsMiddleware

def call(env)

def call(env)
  @bad_headers = ["HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED_HOST", "HTTP_X_FORWARDED_PORT", "HTTP_X_FORWARDED_PROTO", "HTTP_X_FORWARDED_SCHEME", "HTTP_X_FORWARDED_SSL"] 
  if !ActionDispatch::Request::HTTP_METHODS.include?(env["REQUEST_METHOD"].upcase)
    [405, {"Content-Type" => "text/plain"}, ["Method Not Allowed"]]
  else
    if (env['HTTP_ZUORA_LAYOUT_FETCH_TEMPLATE_ID'].present?)
      Thread.current[:isHallway] = "/#{env['HTTP_ZUORA_LAYOUT_FETCH_TEMPLATE_ID']}"
      env['PATH_INFO'] = env['PATH_INFO'].gsub(Thread.current[:isHallway], '')
      env['REQUEST_URI'] = env['REQUEST_URI'].gsub(Thread.current[:isHallway], '')
      env['REQUEST_PATH'] = env['REQUEST_PATH'].gsub(Thread.current[:isHallway], '')
      #We need the forwarded host header to identify location of tenant
      whitelist = Regexp.new(".*[\.]zuora[\.]com$|^zuora[\.]com$")
      if whitelist.match(env['HTTP_X_FORWARDED_HOST']).present?
        @bad_headers.delete('HTTP_X_FORWARDED_HOST')
      end
    else
      Thread.current[:isHallway] = nil
    end
    #Remove bad headers
    @bad_headers.each { |header| env.delete(header) }
    #Thread.current[:appinstance] = nil
    start_time = Time.now
    begin
      @status, @headers, @response = @app.call(env)
    ensure 
      
      # If the url contains any CSS or JavaScript files then do not collect metrics for them
      if ["css", "assets", "jpg", "png", "jpeg", "ico"].any? { |word| env['PATH_INFO'].include?(word) } || /.*\.js$/.match(env['PATH_INFO'])
        tags = {status: @status, controller: 'ActionController', action: 'Assets', app_instance: 0}
        values = {response_time: ((Time.now - start_time)*1000).round(2) }
        ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: 'request-inbound-assets', tags: tags, values: values)
      end
      if defined? Prometheus
        #Prometheus Stuff
        if env['PATH_INFO'] == '/connect/internal/metrics'
          #Do something before each scrape
          if defined? Resque.redis
            begin
              Resque.redis.ping
              Prometheus::REDIS_CONNECTION.set({connection:'redis',name: ZuoraConnect::Telegraf.app_name},1)
              Prometheus::FINISHED_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:processed])
              Prometheus::PENDING_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:pending])
              Prometheus::ACTIVE_WORKERS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:working])
              Prometheus::WORKERS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:workers])
              Prometheus::FAILED_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:failed])
            rescue Redis::CannotConnectError
                Prometheus::REDIS_CONNECTION.set({connection:'redis',name: ZuoraConnect::Telegraf.app_name},0)
            end
            if ZuoraConnect.configuration.custom_prometheus_update_block != nil
              ZuoraConnect.configuration.custom_prometheus_update_block.call()
            end
          end
        end
      end
      # Uncomment following block of code for handling engine requests/requests without controller
      # else
      #   # Handling requests which do not have controllers (engines)
      if env["SCRIPT_NAME"].present?
        controller_path = "#{env['SCRIPT_NAME'][1..-1]}"
        controller_path = controller_path.sub("/", "::")
        request_path = "#{controller_path}#UnknownAction"
      else
        # Writing to telegraf: Handle 404
        if [404, 500].include?(@status)
          content_type = @headers['Content-Type'].split(';')[0] if @headers['Content-Type']
          content_type = content_type.gsub('text/javascript', 'application/javascript')
          tags = {status: @status, content_type: content_type}
       
          tags = tags.merge({controller: 'ActionController'})
          tags = tags.merge({action: 'RoutingError' }) if @status == 404
          
          values = {response_time: ((Time.now - start_time)*1000).round(2) }
          ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
        end
      end
      Thread.current[:inbound_metric] = nil
    end
    [@status, @headers, @response]
  end
end