# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details.
# frozen_string_literal: true

cs__scoped_require 'contrast/framework/rails/patch/rails_application_configuration'
cs__scoped_require 'contrast/agent/patching/policy/after_load_patch'

module Contrast
  module Framework
    module Rails
      module Patch
        # Extension point allowing for the registration of Patches required to
        # support the Rails framework.
        module Support
          # (See BaseSupport#before_load_patches)
          def before_load_patches!
            return unless defined?(::Rails)

            # In Rails, session configuration occurs extremely early & only once.
            # If we defer our patching of the rails session configuration too long
            # (i.e., where we normally patch) we will miss the configuration
            # and will never be able to report session misconfiguration rules.
            Contrast::Framework::Rails::Patch::RailsApplicationConfiguration.instrument
            cs__scoped_require 'contrast/agent/railtie' if ::Rails::VERSION::MAJOR.to_i >= 3
          end

          # (See BaseSupport#after_load_patches)
          def after_load_patches
            Set.new([
                      Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                          'ActionController::Live::Buffer',
                          'contrast/framework/rails/patch/action_controller_live_buffer',
                          instrumenting_module: 'Contrast::Framework::Rails::Patch::ActionControllerLiveBuffer'),
                      Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                          'Rails::Application::Configuration',
                          'contrast/framework/rails/patch/rails_application_configuration',
                          method_to_instrument: :session_store,
                          instrumenting_module: 'Contrast::Framework::Rails::Patch::RailsApplicationConfiguration'),

                      # TODO: RUBY-714 remove w/ EOL of 2.5
                      #
                      # @deprecated  Everything past here is used for Rewriting and can
                      #   be removed once we no longer support 2.5.
                      Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                          'ActionController::Railties::Helper::ClassMethods',
                          'contrast/framework/rails/rewrite/action_controller_railties_helper_inherited',
                          method_to_instrument: :inherited,
                          instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActionControllerRailtiesHelperInherited'),
                      Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                          'ActiveRecord::AttributeMethods::Read::ClassMethods',
                          'contrast/framework/rails/rewrite/active_record_attribute_methods_read',
                          instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordAttributeMethodsRead'),
                      Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                          'ActiveRecord::Scoping::Named::ClassMethods',
                          'contrast/framework/rails/rewrite/active_record_named',
                          instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordNamed'),
                      Contrast::Agent::Patching::Policy::AfterLoadPatch.new(
                          'ActiveRecord::AttributeMethods::TimeZoneConversion::ClassMethods',
                          'contrast/framework/rails/rewrite/active_record_time_zone_inherited',
                          method_to_instrument: :inherited,
                          instrumenting_module: 'Contrast::Framework::Rails::Rewrite::ActiveRecordTimeZoneInherited')
                    ])
          end
        end
      end
    end
  end
end