require 'rspec/core/hooks'
require './core/configs/grid_config'
require './core/utils/logger_utils'

module RSpec
  module Core
    module Hooks
      include GridConfig
      include LoggerUtils

      def before(*args, &block)
        if args.include?(:all) # Only look at before(:all) blocks
          block_to_execute = Proc.new do
            attempts = 0
            max_attempts = 10

            begin
              attempts += 1
              self.instance_exec(&block)
            rescue Exception => e
              logger.warn "Caught [#{e.class}] in before hook. Message: #{e.message}"
              if grid_connection_terminated?(e)
                reconnect_to_grid

                if attempts < max_attempts
                  logger.info "Retrying before block. Attempt: #{attempts + 1}/#{max_attempts}"
                  retry
                else
                  logger.warn 'Max attempts reached retrying before block.'
                  raise e # Max attempts reached
                end
              else
                raise e # Not a Grid Terminated Exception
              end
            end
          end
        else
          block_to_execute = block # Not a before(:all) block. Assigning original param block.
        end

        hooks.register :append, :before, *args, &block_to_execute
      end
    end
  end
end
