# frozen_string_literal: true

require "test_helper"

class ExpiredRulesCleanupJobTest < ActiveJob::TestCase
  test "disables expired rules" do
    expired_range = NetworkRange.create!(cidr: "10.0.0.0/8")
    expired_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: expired_range,
      expires_at: 1.hour.ago,
      enabled: true
    )

    active_range = NetworkRange.create!(cidr: "192.168.0.0/16")
    active_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: active_range,
      expires_at: 1.hour.from_now,
      enabled: true
    )

    count = ExpiredRulesCleanupJob.perform_now

    assert_equal 1, count
    assert_not expired_rule.reload.enabled?
    assert active_rule.reload.enabled?
  end

  test "does not affect rules without expiration" do
    permanent_range = NetworkRange.create!(cidr: "10.0.0.0/8")
    permanent_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: permanent_range,
      expires_at: nil,
      enabled: true
    )

    ExpiredRulesCleanupJob.perform_now

    assert permanent_rule.reload.enabled?
  end

  test "does not affect already disabled rules" do
    disabled_range = NetworkRange.create!(cidr: "10.0.0.0/8")
    disabled_expired_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: disabled_range,
      expires_at: 1.hour.ago,
      enabled: false
    )

    count = ExpiredRulesCleanupJob.perform_now

    assert_equal 0, count
    assert_not disabled_expired_rule.reload.enabled?
  end

  test "updates updated_at timestamp when disabling" do
    expired_range = NetworkRange.create!(cidr: "10.0.0.0/8")
    expired_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: expired_range,
      expires_at: 1.hour.ago,
      enabled: true
    )

    original_updated_at = expired_rule.updated_at

    sleep 0.01 # Ensure time passes

    ExpiredRulesCleanupJob.perform_now

    assert expired_rule.reload.updated_at > original_updated_at
  end

  test "deletes old disabled rules when running at 1am" do
    old_range = NetworkRange.create!(cidr: "10.0.0.0/8")
    old_disabled_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: old_range,
      enabled: false
    )
    old_disabled_rule.update_column(:updated_at, 31.days.ago)

    recent_range = NetworkRange.create!(cidr: "192.168.0.0/16")
    recent_disabled_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: recent_range,
      enabled: false
    )

    Time.stub :current, Time.current.change(hour: 1) do
      ExpiredRulesCleanupJob.perform_now
    end

    assert_raises(ActiveRecord::RecordNotFound) { old_disabled_rule.reload }
    assert_nothing_raised { recent_disabled_rule.reload }
  end

  test "does not delete old rules when not running at 1am" do
    old_range = NetworkRange.create!(cidr: "10.0.0.0/8")
    old_disabled_rule = Rule.create!(
      waf_rule_type: "network",
      waf_action: "deny",
      network_range: old_range,
      enabled: false
    )
    old_disabled_rule.update_column(:updated_at, 31.days.ago)

    Time.stub :current, Time.current.change(hour: 10) do
      ExpiredRulesCleanupJob.perform_now
    end

    assert_nothing_raised { old_disabled_rule.reload }
  end

  test "returns count of disabled rules" do
    3.times do |i|
      range = NetworkRange.create!(cidr: "10.#{i}.0.0/16")
      Rule.create!(
        waf_rule_type: "network",
        waf_action: "deny",
        network_range: range,
        expires_at: 1.hour.ago,
        enabled: true
      )
    end

    count = ExpiredRulesCleanupJob.perform_now

    assert_equal 3, count
  end

  test "returns zero when no expired rules" do
    count = ExpiredRulesCleanupJob.perform_now

    assert_equal 0, count
  end
end
