class AlignWafActionEnums < ActiveRecord::Migration[8.1]
  def up
    # Current enum mapping (BEFORE):
    # allow: 0, deny: 1, rate_limit: 2, redirect: 3, log: 4, challenge: 5
    #
    # Target enum mapping (AFTER):
    # deny: 0, allow: 1, redirect: 2, challenge: 3, log: 4
    #
    # Strategy: Use temporary values to avoid conflicts during swap

    say "Aligning WAF action enums to canonical order (deny:0, allow:1, redirect:2, challenge:3, log:4)"

    # === Rules Table ===
    say_with_time "Updating rules table..." do
      # Temporarily disable triggers to avoid FK constraint issues during enum swap
      execute "SET session_replication_role = replica;"

      # Step 1: Move existing values to temporary range (100+)
      execute <<-SQL
        UPDATE rules
        SET waf_action = CASE
          WHEN waf_action = 0 THEN 100  -- allow -> temp(100)
          WHEN waf_action = 1 THEN 101  -- deny -> temp(101)
          WHEN waf_action = 2 THEN 102  -- rate_limit -> temp(102)
          WHEN waf_action = 3 THEN 103  -- redirect -> temp(103)
          WHEN waf_action = 4 THEN 104  -- log -> temp(104)
          WHEN waf_action = 5 THEN 105  -- challenge -> temp(105)
          ELSE waf_action
        END
      SQL

      # Step 2: Move from temporary to final positions
      execute <<-SQL
        UPDATE rules
        SET waf_action = CASE
          WHEN waf_action = 101 THEN 0  -- deny -> 0
          WHEN waf_action = 100 THEN 1  -- allow -> 1
          WHEN waf_action = 103 THEN 2  -- redirect -> 2
          WHEN waf_action = 105 THEN 3  -- challenge -> 3
          WHEN waf_action = 104 THEN 4  -- log -> 4
          WHEN waf_action = 102 THEN 0  -- rate_limit -> deny (rate_limit is a rule_type, not action)
          ELSE waf_action
        END
      SQL

      # Re-enable triggers
      execute "SET session_replication_role = DEFAULT;"

      # Return count without triggering model validations
      connection.execute("SELECT COUNT(*) FROM rules").first["count"]
    end

    # === Events Table ===
    say_with_time "Updating events table..." do
      # Step 1: Move existing values to temporary range (100+)
      execute <<-SQL
        UPDATE events
        SET waf_action = CASE
          WHEN waf_action = 0 THEN 100  -- allow -> temp(100)
          WHEN waf_action = 1 THEN 101  -- deny -> temp(101)
          WHEN waf_action = 2 THEN 102  -- redirect -> temp(102)
          WHEN waf_action = 3 THEN 103  -- challenge -> temp(103)
          ELSE waf_action
        END
      SQL

      # Step 2: Move from temporary to final positions
      execute <<-SQL
        UPDATE events
        SET waf_action = CASE
          WHEN waf_action = 101 THEN 0  -- deny -> 0
          WHEN waf_action = 100 THEN 1  -- allow -> 1
          WHEN waf_action = 102 THEN 2  -- redirect -> 2
          WHEN waf_action = 103 THEN 3  -- challenge -> 3
          ELSE waf_action
        END
      SQL

      # Return count without triggering model validations
      connection.execute("SELECT COUNT(*) FROM events").first["count"]
    end

    say "Enum alignment complete!", true
  end

  def down
    # Reverse the migration - swap back to old order
    say "Reverting WAF action enums to original order"

    # === Rules Table ===
    say_with_time "Reverting rules table..." do
      execute <<-SQL
        UPDATE rules
        SET waf_action = CASE
          WHEN waf_action = 0 THEN 100  -- deny -> temp(100)
          WHEN waf_action = 1 THEN 101  -- allow -> temp(101)
          WHEN waf_action = 2 THEN 102  -- redirect -> temp(102)
          WHEN waf_action = 3 THEN 103  -- challenge -> temp(103)
          WHEN waf_action = 4 THEN 104  -- log -> temp(104)
          ELSE waf_action
        END
      SQL

      execute <<-SQL
        UPDATE rules
        SET waf_action = CASE
          WHEN waf_action = 101 THEN 0  -- allow -> 0
          WHEN waf_action = 100 THEN 1  -- deny -> 1
          WHEN waf_action = 104 THEN 4  -- log -> 4
          WHEN waf_action = 103 THEN 3  -- redirect -> 3
          WHEN waf_action = 102 THEN 2  -- rate_limit -> 2 (restore even though deprecated)
          WHEN waf_action = 105 THEN 5  -- challenge -> 5
          ELSE waf_action
        END
      SQL

      # Return count without triggering model validations
      connection.execute("SELECT COUNT(*) FROM rules").first["count"]
    end

    # === Events Table ===
    say_with_time "Reverting events table..." do
      execute <<-SQL
        UPDATE events
        SET waf_action = CASE
          WHEN waf_action = 0 THEN 100  -- deny -> temp(100)
          WHEN waf_action = 1 THEN 101  -- allow -> temp(101)
          WHEN waf_action = 2 THEN 102  -- redirect -> temp(102)
          WHEN waf_action = 3 THEN 103  -- challenge -> temp(103)
          ELSE waf_action
        END
      SQL

      execute <<-SQL
        UPDATE events
        SET waf_action = CASE
          WHEN waf_action = 101 THEN 0  -- allow -> 0
          WHEN waf_action = 100 THEN 1  -- deny -> 1
          WHEN waf_action = 102 THEN 2  -- redirect -> 2
          WHEN waf_action = 103 THEN 3  -- challenge -> 3
          ELSE waf_action
        END
      SQL

      # Return count without triggering model validations
      connection.execute("SELECT COUNT(*) FROM events").first["count"]
    end

    say "Revert complete!", true
  end
end
