# frozen_string_literal: true

module Service
  class StructuredLogger
    def self.error(type, options = {})
      Rails.logger.error({
        _type: type,
      }.update(options).to_json)
    end

    def self.info(type, options = {})
      Rails.logger.info({
        _type: type,
      }.update(options).to_json)
    end
  end

  # Log backend requests made with availability statistics
  class ResponseLogger < Faraday::Middleware
    def call(env)
      start_time = Time.now

      begin
        response = @app.call env
      rescue Faraday::Error => err
        StructuredLogger.error(
          'backend_service_call_error',
          time_log(start_time)
            .update(env_log(env))
            .update(error_log(err))
        )

        raise err
      else
        StructuredLogger.info(
          'backend_service_call_success',
          time_log(start_time)
            .update(env_log(env))
            .update(response_log(response))
        )
      end

      response
    end

    protected

    def time_log(start)
      {
        access_date: start,
        latency: Time.now - start,
      }
    end

    def env_log(env)
      {
        method: env[:method],
        url_host: env[:url].host,
        url_path: env[:url].path,
        url_scheme: env[:url].scheme,
        url_query: env[:url].query
      }
    end

    def response_log(response)
      return {} unless response

      return {
        response_status: response.status
      }
    end

    def error_log(error)
      return {} unless error

      return {
        error_message: error.message
      }
    end
  end
end
