class Maintenance::SiteDumpJob
  # Code generated, partially by Cursor
  include Sidekiq::Worker
  require 'zlib'

  # Base directory for all school-related data operations
  BACKUP_BASE_DIR = '/mnt/data/backups/schools'.freeze

  # Backup retention settings
  BACKUP_RETENTION = {
    max_backups_per_school: 5,    # Maximum number of backup files to keep per school
    max_backup_age_days: 30       # Maximum age of backup files in days
  }.freeze

  # Tables that should not be included in the school data dump
  EXCLUDED_TABLES = %w[
    APIKeys
    APILogs
    APITokens
    UserSupport
    UserSupportLogs
    UserSupportTickets
    UserSupportTicketLogs
    UserSupportTicketComments
  ].freeze

  # School ID column names to check in tables
  SCHOOL_ID_COLUMNS = %w[SchoolID school_id].freeze

  def perform(school_id)
    school_id = school_id.to_i  # Ensure school_id is an integer
    begin
      Rails.logger.info("Starting data export for school #{school_id}")
      FileUtils.mkdir_p(BACKUP_BASE_DIR)

      output_dir = create_output_directory(school_id)
      cleanup_old_backups(school_id)

      timestamp = Time.current.strftime('%Y%m%d_%H%M%S')
      sql_file = output_dir.join("school_#{school_id}_#{timestamp}.sql")
      gz_file = output_dir.join("school_#{school_id}_#{timestamp}.sql.gz")
      lock_file = output_dir.join("school_#{school_id}.lock")

      # Try to acquire lock
      File.open(lock_file, File::RDWR | File::CREAT) do |f|
        if f.flock(File::LOCK_EX | File::LOCK_NB)
          begin
            dump_data(school_id, sql_file)
            gzip_file(sql_file, gz_file)

            File.unlink(sql_file) # Remove the SQL file after compression
            Rails.logger.info("Data export completed and compressed: #{gz_file}")

            # Verify the backup
            verify_backup(gz_file)
          ensure
            f.flock(File::LOCK_UN)
          end
        else
          raise "Another backup process is already running for school #{school_id}"
        end
      end
    rescue StandardError => e
      Rails.logger.error("Backup failed for school #{school_id}: #{e.message}")
      cleanup_failed_backup(sql_file, gz_file)
      raise
    ensure
      File.unlink(lock_file) if lock_file && File.exist?(lock_file)
    end
  end

  private
    def create_output_directory(school_id)
      dir = Pathname.new(BACKUP_BASE_DIR).join(school_id.to_s)
      
      # Check if we have write permissions to the backup directory
      unless File.writable?(BACKUP_BASE_DIR) || !File.exist?(BACKUP_BASE_DIR)
        raise "No write permission for backup directory: #{BACKUP_BASE_DIR}"
      end
      
      FileUtils.mkdir_p(dir)
      
      # Verify the created directory is writable
      unless File.writable?(dir)
        raise "Created directory is not writable: #{dir}"
      end
      
      dir
    end

    def cleanup_old_backups(school_id)
      backup_dir = Pathname.new(BACKUP_BASE_DIR).join(school_id.to_s)
      return unless File.directory?(backup_dir)

      Rails.logger.info("Cleaning up old backups for school #{school_id}")

      begin
        # Get all backup files sorted by modification time (newest first)
        backup_files = Dir.glob(backup_dir.join("*.sql.gz"))
          .select { |f| File.exist?(f) }
          .sort_by { |f| File.mtime(f) }
          .reverse

        # Remove old backups exceeding the maximum count
        if backup_files.size > BACKUP_RETENTION[:max_backups_per_school]
          backup_files[BACKUP_RETENTION[:max_backups_per_school]..-1].each do |file|
            begin
              if File.exist?(file)
                Rails.logger.info("Removing excess backup: #{file}")
                File.unlink(file)
              end
            rescue => e
              Rails.logger.warn("Failed to remove excess backup #{file}: #{e.message}")
            end
          end
        end

        # Remove backups older than the maximum age
        max_age = Time.current - BACKUP_RETENTION[:max_backup_age_days].days
        backup_files.each do |file|
          begin
            if File.exist?(file) && File.mtime(file) < max_age
              Rails.logger.info("Removing expired backup: #{file}")
              File.unlink(file)
            end
          rescue => e
            Rails.logger.warn("Failed to remove expired backup #{file}: #{e.message}")
          end
        end
      rescue => e
        Rails.logger.error("Error during backup cleanup for school #{school_id}: #{e.message}")
      end
    end

    def verify_backup(backup_file)
      Rails.logger.info("Verifying backup file: #{backup_file}")
      
      unless File.exist?(backup_file)
        raise "Backup file not found: #{backup_file}"
      end

      if File.size(backup_file) == 0
        raise "Backup file is empty: #{backup_file}"
      end

      # Try to read the gzip file to ensure it's not corrupted
      Zlib::GzipReader.open(backup_file) { |gz| gz.read(1024) }
      
      Rails.logger.info("Backup verification completed successfully")
    end

    def cleanup_failed_backup(sql_file, gz_file)
      [sql_file, gz_file].each do |file|
        if file && File.exist?(file)
          Rails.logger.info("Cleaning up failed backup file: #{file}")
          File.unlink(file)
        end
      end
    end

    def get_school_tables
      Rails.logger.info("Finding tables with school ID columns (SchoolID or school_id)...")
      excluded_tables = EXCLUDED_TABLES.map { |t| ActiveRecord::Base.connection.quote(t) }.join(',')

      tables = ActiveRecord::Base.connection.execute(<<~SQL).map { |row| row[0].to_s }
        SELECT DISTINCT TABLE_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
          AND COLUMN_NAME IN (#{SCHOOL_ID_COLUMNS.map { |c| ActiveRecord::Base.connection.quote(c) }.join(',')})
          AND TABLE_NAME NOT IN (#{excluded_tables})
        ORDER BY TABLE_NAME
      SQL

      Rails.logger.info("Found #{tables.size} tables with school ID columns:")
      tables.each { |t| Rails.logger.info("  - #{t}") }
      tables
    end

    def get_school_id_column(table)
      # We only expect one school ID column per table
      result = ActiveRecord::Base.connection.execute(<<~SQL)
        SELECT COLUMN_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_SCHEMA = DATABASE()
          AND TABLE_NAME = #{ActiveRecord::Base.connection.quote(table)}
          AND COLUMN_NAME IN (#{SCHOOL_ID_COLUMNS.map { |c| ActiveRecord::Base.connection.quote(c) }.join(',')})
        LIMIT 1
      SQL
      
      column = result.first&.first
      Rails.logger.debug("Found school ID column for #{table}: #{column || 'none'}")
      column
    end

    def get_related_tables(root_tables)
      Rails.logger.info("Finding related tables through foreign keys...")

      begin
        # Get all foreign key relationships
        relationships = ActiveRecord::Base.connection.execute(<<~SQL)
          SELECT
            TABLE_NAME,
            COLUMN_NAME,
            REFERENCED_TABLE_NAME,
            REFERENCED_COLUMN_NAME
          FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
          WHERE TABLE_SCHEMA = DATABASE()
            AND REFERENCED_TABLE_NAME IS NOT NULL
            AND TABLE_NAME NOT IN (#{EXCLUDED_TABLES.map { |t| ActiveRecord::Base.connection.quote(t) }.join(',')})
        SQL

        # Build relationship graph
        graph = {}
        relationships.each do |rel|
          begin
            # Ensure we're working with strings for table names and they're not nil
            from = rel['TABLE_NAME'].to_s
            to = rel['REFERENCED_TABLE_NAME'].to_s
            
            if from.nil? || from.to_s.strip.empty? || to.nil? || to.to_s.strip.empty?
              Rails.logger.warn("Skipping relationship with invalid table name: #{rel.inspect}")
              next
            end

            # Initialize graph entries if they don't exist
            graph[from] ||= { references: [], referenced_by: [] }
            graph[to] ||= { references: [], referenced_by: [] }

            # Add relationships with string keys
            relationship = {
              table: to,
              column: rel['COLUMN_NAME'].to_s,
              ref_column: rel['REFERENCED_COLUMN_NAME'].to_s
            }

            # Log the relationship being added
            Rails.logger.debug("Adding relationship: #{from} -> #{to} (#{relationship[:column]} -> #{relationship[:ref_column]})")

            graph[from][:references] << relationship
            graph[to][:referenced_by] << {
              table: from,
              column: rel['COLUMN_NAME'].to_s,
              ref_column: rel['REFERENCED_COLUMN_NAME'].to_s
            }
          rescue => e
            Rails.logger.error("Error processing relationship: #{rel.inspect}")
            Rails.logger.error("Error details: #{e.message}")
            next
          end
        end

        # Ensure root_tables are strings and valid
        root_tables = root_tables.map(&:to_s).reject { |t| t.nil? || t.strip.empty? }
        Rails.logger.info("Processing root tables: #{root_tables.join(', ')}")

        # Find all connected tables starting from root tables
        connected = Set.new(root_tables)
        queue = root_tables.dup

        while table = queue.shift
          begin
            next if table.nil? || table.to_s.strip.empty?
            next unless graph[table]

            Rails.logger.debug("Processing connections for table: #{table}")

            # Check tables that reference this table
            graph[table][:referenced_by].each do |ref|
              next if ref[:table].nil? || ref[:table].to_s.strip.empty?
              next if connected.include?(ref[:table])
              Rails.logger.debug("Adding referenced table: #{ref[:table]}")
              connected << ref[:table]
              queue << ref[:table]
            end

            # Check tables that this table references
            graph[table][:references].each do |ref|
              next if ref[:table].nil? || ref[:table].to_s.strip.empty?
              next if connected.include?(ref[:table])
              Rails.logger.debug("Adding referencing table: #{ref[:table]}")
              connected << ref[:table]
              queue << ref[:table]
            end
          rescue => e
            Rails.logger.error("Error processing table relationships for #{table}: #{e.message}")
            next
          end
        end

        related_tables = connected.to_a - root_tables
        Rails.logger.info("Found #{related_tables.size} related tables: #{related_tables.join(', ')}")

        # Return both the connected tables and the relationship graph
        [connected.to_a, graph]
      rescue => e
        Rails.logger.error("Error in get_related_tables: #{e.message}")
        Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
        raise
      end
    end

    def get_primary_key(table)
      # Get the primary key column(s) for the table
      result = ActiveRecord::Base.connection.execute(<<~SQL)
        SELECT k.COLUMN_NAME
        FROM information_schema.table_constraints t
        JOIN information_schema.key_column_usage k
        USING(constraint_name,table_schema,table_name)
        WHERE t.constraint_type='PRIMARY KEY'
          AND t.table_schema=DATABASE()
          AND t.table_name=#{ActiveRecord::Base.connection.quote(table)}
        ORDER BY k.ordinal_position;
      SQL
      
      # Handle different result formats (array or hash)
      result.map do |row|
        if row.is_a?(Hash)
          row['COLUMN_NAME']
        elsif row.respond_to?(:first)
          row.first
        else
          row.to_s
        end
      end.compact
    rescue => e
      Rails.logger.error("Error getting primary key for table #{table}: #{e.message}")
      Rails.logger.error("Result: #{result.inspect}")
      Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
      []
    end

    def dump_data(school_id, output_file)
      Rails.logger.info("Starting data dump for school_id=#{school_id}...")
      
      # Get root tables (those with school_id)
      root_tables = get_school_tables
      
      if root_tables.empty?
        Rails.logger.error("No tables found with SchoolID or school_id columns!")
        return
      end

      # Get all related tables
      all_tables, relationships = get_related_tables(root_tables)
      
      Rails.logger.info("Found #{all_tables.size} tables to export:")
      Rails.logger.info("  - #{root_tables.size} root tables with school ID columns")
      Rails.logger.info("  - #{all_tables.size - root_tables.size} related tables through foreign keys")
      
      File.open(output_file, 'w') do |file|
        # Add header with metadata
        file.puts("-- Dumping data for school_id: #{school_id}")
        file.puts("-- Generated at: #{Time.current}")
        file.puts("-- Root tables: #{root_tables.join(', ')}")
        file.puts("-- Related tables: #{(all_tables - root_tables).join(', ')}")
        file.puts

        # Add commands to disable foreign key checks
        file.puts("/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;")
        file.puts("/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;")
        file.puts

        # First dump root tables
        root_tables.each do |table|
          Rails.logger.info("Processing root table #{table} and its relationships...")
          ids = dump_root_table(table, school_id, file)
          
          if ids.empty?
            Rails.logger.warn("No data found in root table #{table} for school_id #{school_id}")
            next
          end
          
          Rails.logger.info("Found #{ids.size} records in #{table}, following relationships...")
          
          # Then dump related data
          dump_related_data(table, ids, relationships, file, Set.new([table]))
        end

        # Restore foreign key checks
        file.puts
        file.puts("/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;")
        file.puts("/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;")
      end

      unless File.exist?(output_file.to_s) && File.size(output_file.to_s) > 0
        raise "Data dump produced empty output file"
      end

      Rails.logger.info("Dump completed successfully")
      Rails.logger.info("File size: #{File.size(output_file.to_s)} bytes")
    end

    def dump_root_table(table, school_id, file)
      begin
        school_id_column = get_school_id_column(table)
        unless school_id_column
          Rails.logger.warn("No school ID column found for table #{table}, skipping")
          return []
        end

        Rails.logger.info("Processing root table: #{table} using column: #{school_id_column}")
        
        # Quote the school_id value for safe SQL
        safe_school_id = ActiveRecord::Base.connection.quote(school_id)
        where_condition = "`#{table}`.`#{school_id_column}`=#{safe_school_id}"
        
        Rails.logger.debug("Executing query for #{table} with condition: #{where_condition}")

        # Get the data
        count_result = ActiveRecord::Base.connection.execute(<<~SQL)
          SELECT COUNT(*) as count
          FROM `#{table}`
          WHERE #{where_condition}
        SQL
        
        # Handle different result formats (array or hash)
        matching_rows = if count_result.first.is_a?(Hash)
          count_result.first['count']
        else
          count_result.first[0]
        end.to_i

        Rails.logger.info("Found #{matching_rows} rows in #{table} for school_id #{school_id}")

        if matching_rows == 0
          Rails.logger.warn("No matching rows found in #{table} for school_id #{school_id}")
          return []
        end

        # Now get the actual data
        result = ActiveRecord::Base.connection.execute(<<~SQL)
          SELECT *
          FROM `#{table}`
          WHERE #{where_condition}
        SQL

        Rails.logger.debug("Retrieved #{result.count} rows for #{table}")

        ids = dump_rows(table, result, file, where_condition)
        Rails.logger.info("Processed #{ids.size} primary key values from root table #{table}")
        
        if ids.empty?
          Rails.logger.warn("No primary keys extracted from #{table} despite having #{result.count} rows")
          Rails.logger.debug("Sample row from result: #{result.first.inspect}")
        else
          Rails.logger.debug("Sample of primary keys from #{table}: #{ids.first(3).inspect}")
        end

        ids
      rescue => e
        Rails.logger.error("Error in dump_root_table for #{table}: #{e.message}")
        Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
        Rails.logger.error("Table: #{table.inspect}")
        Rails.logger.error("School ID: #{school_id.inspect}")
        []
      end
    end

    def dump_related_data(source_table, source_ids, relationships, file, processed_tables)
      begin
        source_table_key = source_table.to_s
        Rails.logger.debug("Processing related data for table: #{source_table_key}")
        Rails.logger.debug("Source primary keys before processing: #{source_ids.inspect}")
        
        return unless relationships[source_table_key]  # Ensure string key

        # Handle tables that reference this table
        relationships[source_table_key][:referenced_by].each do |ref|
          begin
            next if ref[:table].nil? || ref[:table].to_s.strip.empty?
            next if processed_tables.include?(ref[:table])
            processed_tables << ref[:table]

            Rails.logger.info("Processing related table: #{ref[:table]} (references #{source_table_key})")

            # Handle composite keys or non-integer primary keys
            where_condition = if source_ids.first.is_a?(Hash)
              conditions = source_ids.map do |id_hash|
                id_hash.map { |col, val| 
                  quoted_val = ActiveRecord::Base.connection.quote(val)
                  "`#{ref[:table]}`.`#{ref[:column]}`=#{quoted_val}"
                }.join(" AND ")
              end
              "(#{conditions.join(") OR (")})"
            else
              # Quote each value individually to handle mixed types
              values = source_ids.map { |id| ActiveRecord::Base.connection.quote(id) }.join(',')
              "`#{ref[:table]}`.`#{ref[:column]}` IN (#{values})"
            end

            Rails.logger.debug("Executing query with condition: #{where_condition}")
            result = ActiveRecord::Base.connection.execute(<<~SQL)
              SELECT *
              FROM `#{ref[:table]}`
              WHERE #{where_condition}
            SQL

            # Skip if no results
            next if result.count == 0

            ids = dump_rows(ref[:table], result, file, where_condition)
            Rails.logger.debug("Got #{ids.size} primary key values from #{ref[:table]}")
            next if ids.empty?

            # Recursively follow relationships
            dump_related_data(ref[:table], ids, relationships, file, processed_tables)
          rescue => e
            Rails.logger.error("Error processing referenced table #{ref[:table]}: #{e.message}")
            Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
            next
          end
        end

        # Handle tables that this table references
        relationships[source_table_key][:references].each do |ref|
          begin
            next if ref[:table].nil? || ref[:table].to_s.strip.empty?
            next if processed_tables.include?(ref[:table])
            processed_tables << ref[:table]

            Rails.logger.info("Processing related table: #{ref[:table]} (referenced by #{source_table_key})")
            
            # Handle composite keys or non-integer primary keys
            join_condition = if source_ids.first.is_a?(Hash)
              source_ids.map do |id_hash|
                id_hash.map { |col, val| 
                  quoted_val = ActiveRecord::Base.connection.quote(val)
                  "s.`#{col}` = #{quoted_val}"
                }.join(" AND ")
              end.join(" OR ")
            else
              # Quote each value individually to handle mixed types
              values = source_ids.map { |id| ActiveRecord::Base.connection.quote(id) }.join(',')
              "s.id IN (#{values})"
            end

            Rails.logger.debug("Executing join query for #{ref[:table]}")
            result = ActiveRecord::Base.connection.execute(<<~SQL)
              SELECT DISTINCT r.*
              FROM `#{ref[:table]}` r
              INNER JOIN `#{source_table_key}` s ON r.`#{ref[:ref_column]}` = s.`#{ref[:column]}`
              WHERE #{join_condition}
            SQL

            # Skip if no results
            next if result.count == 0

            ids = dump_rows(ref[:table], result, file, "Referenced by #{source_table_key}")
            Rails.logger.debug("Got #{ids.size} primary key values from #{ref[:table]}")
            next if ids.empty?

            # Recursively follow relationships
            dump_related_data(ref[:table], ids, relationships, file, processed_tables)
          rescue => e
            Rails.logger.error("Error processing referencing table #{ref[:table]}: #{e.message}")
            Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
            next
          end
        end
      rescue => e
        Rails.logger.error("Error in dump_related_data for #{source_table.inspect}: #{e.message}")
        Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
        raise
      end
    end

    def dump_rows(table, result, file, condition_desc)
      # Check if result is empty using count for MySQL result
      return [] if result.count == 0

      # Get column names and types
      columns_info = ActiveRecord::Base.connection.execute("SHOW COLUMNS FROM `#{table}`")
      columns = columns_info.map { |row| row.is_a?(Hash) ? row['Field'] : row[0] }

      file.puts
      file.puts("-- Table: #{table}")
      file.puts("-- Filter: #{condition_desc}")

      result.each do |row|
        begin
          # Convert row to hash if it's an array
          row_data = if row.is_a?(Array)
            Hash[columns.zip(row)]
          elsif row.respond_to?(:to_h)
            row.to_h
          else
            row
          end

          # Ensure we have a hash with string keys
          row_data = row_data.transform_keys(&:to_s) if row_data.is_a?(Hash)
          
          Rails.logger.debug("Processing row: #{row_data.inspect}") if row_data.nil? || !row_data.is_a?(Hash)
          
          # Handle both string and symbol column names
          values = columns.map do |col|
            val = if row_data.is_a?(Hash)
              row_data[col.to_s] || row_data[col.to_sym]
            else
              Rails.logger.warn("Unexpected row format in #{table}: #{row_data.class}")
              nil
            end
            # Convert to string, handling nil values
            val_str = val.nil? ? 'NULL' : val.to_s
            ActiveRecord::Base.connection.quote(val_str)
          end
          
          file.puts("INSERT INTO `#{table}` (`#{columns.join('`, `')}`) VALUES (#{values.join(', ')});")
        rescue => e
          Rails.logger.error("Error processing row in #{table}: #{e.message}")
          Rails.logger.error("Row data: #{row.inspect}")
          Rails.logger.error("Processed row data: #{row_data.inspect}") if defined?(row_data)
          next
        end
      end

      Rails.logger.info("  Exported #{result.count} rows from #{table}")

      # Return primary keys for relationship tracking
      begin
        # Get the primary key columns
        primary_keys = get_primary_key(table)
        
        if primary_keys.empty?
          Rails.logger.warn("Table #{table} does not have a primary key, skipping relationship tracking")
          return []
        end

        Rails.logger.debug("Using primary key(s) for #{table}: #{primary_keys.join(', ')}")
        Rails.logger.debug("First row sample: #{result.first.inspect}")

        # For each row, collect all primary key values
        row_identifiers = []
        result.each do |row|
          begin
            # Convert row to hash if it's an array
            row_data = if row.is_a?(Array)
              Hash[columns.zip(row)]
            elsif row.respond_to?(:to_h)
              row.to_h
            else
              row
            end

            # Ensure we have a hash with string keys
            row_data = row_data.transform_keys(&:to_s) if row_data.is_a?(Hash)
            
            # For composite keys, we'll create a hash of all key parts
            if primary_keys.size > 1
              identifier = {}
              primary_keys.each do |key|
                # Try both string and symbol keys
                val = if row_data.is_a?(Hash)
                  row_data[key.to_s] || row_data[key.to_sym]
                else
                  Rails.logger.warn("Unexpected row format for primary key in #{table}: #{row_data.class}")
                  nil
                end
                next if val.nil?
                
                # Convert the value to string to avoid type issues
                identifier[key.to_s] = val.to_s
              end
              row_identifiers << identifier unless identifier.empty?
            else
              # Single primary key
              key = primary_keys.first.to_s
              # Try both string and symbol keys
              val = if row_data.is_a?(Hash)
                row_data[key] || row_data[key.to_sym]
              else
                Rails.logger.warn("Unexpected row format for primary key in #{table}: #{row_data.class}")
                nil
              end
              
              next if val.nil?
              
              # Convert the value to string to avoid type issues
              row_identifiers << val.to_s
            end
          rescue => e
            Rails.logger.warn("Error processing row primary key in #{table}: #{e.message}")
            Rails.logger.warn("Row data: #{row.inspect}")
            Rails.logger.warn("Processed row data: #{row_data.inspect}") if defined?(row_data)
            Rails.logger.warn("Primary keys: #{primary_keys.inspect}")
            next
          end
        end

        Rails.logger.info("Extracted #{row_identifiers.size} primary key values from #{table}")
        Rails.logger.debug("Sample identifiers: #{row_identifiers.first(3).inspect}")
        row_identifiers
      rescue => e
        Rails.logger.error("Error processing primary keys for #{table}: #{e.message}")
        Rails.logger.error("Table: #{table.inspect}")
        Rails.logger.error("Primary keys: #{primary_keys.inspect}")
        Rails.logger.error("First row: #{result.first.inspect}")
        Rails.logger.error("Backtrace: #{e.backtrace.join("\n")}")
        []
      end
    end

    def gzip_file(input_file, output_file)
      Rails.logger.info("Compressing dump file...")
      
      # Check file size before reading into memory
      file_size = File.size(input_file)
      if file_size > 1.gigabyte
        Rails.logger.warn("Large file detected (#{file_size} bytes), using streaming compression")
        Zlib::GzipWriter.open(output_file) do |gz|
          File.open(input_file, 'rb') do |file|
            while chunk = file.read(16.megabytes)
              gz.write(chunk)
            end
          end
        end
      else
        Zlib::GzipWriter.open(output_file) do |gz|
          gz.write(File.read(input_file))
        end
      end

      Rails.logger.info("Compression completed")
      Rails.logger.info("Gzip file size: #{File.size(output_file)} bytes")
    end
end
