# frozen_string_literal: true

class SwapVulnerabilityOccurrencePipelinesPipelineIdConvertToBigint < Gitlab::Database::Migration[2.2]
  include Gitlab::Database::MigrationHelpers::Swapping

  milestone '17.1'
  disable_ddl_transaction!

  TABLE_NAME = 'vulnerability_occurrence_pipelines'
  COLUMN_NAME = 'pipeline_id'

  COLUMN_TO_BIGINT_NAME = 'pipeline_id_convert_to_bigint'
  INDEX_TO_BIGINT_NAME = 'index_vulnerability_occurrence_pipelines_on_pipeline_id_bigint'
  INDEX_NAME = 'index_vulnerability_occurrence_pipelines_on_pipeline_id'

  UNIQUE_KEYS_INDEX_NAME_BIGINT = 'vulnerability_occurrence_pipelines_on_unique_keys_bigint'
  UNIQUE_KEYS_INDEX_NAME = 'vulnerability_occurrence_pipelines_on_unique_keys'
  UNIQUE_INDEX_COLUMNS = %w[occurrence_id pipeline_id_convert_to_bigint]

  TRIGGER_NAME = :trigger_2ac3d66ed1d3

  def up
    add_concurrent_index TABLE_NAME, COLUMN_TO_BIGINT_NAME, name: INDEX_TO_BIGINT_NAME
    add_concurrent_index TABLE_NAME, UNIQUE_INDEX_COLUMNS,
      name: UNIQUE_KEYS_INDEX_NAME_BIGINT,
      unique: true

    swap
  end

  def down
    add_concurrent_index TABLE_NAME, COLUMN_TO_BIGINT_NAME, name: INDEX_TO_BIGINT_NAME
    add_concurrent_index TABLE_NAME, UNIQUE_INDEX_COLUMNS,
      name: UNIQUE_KEYS_INDEX_NAME_BIGINT,
      unique: true

    swap
  end

  def swap
    with_lock_retries(raise_on_exhaustion: true) do
      # Not locking ci_pipelines as it's an LFK column
      lock_tables(TABLE_NAME)

      swap_columns(TABLE_NAME, COLUMN_NAME, COLUMN_TO_BIGINT_NAME)

      reset_trigger_function(TRIGGER_NAME)

      change_column_default TABLE_NAME, COLUMN_TO_BIGINT_NAME, 0
      change_column_default TABLE_NAME, COLUMN_NAME, nil

      execute "DROP INDEX #{INDEX_NAME}"
      rename_index TABLE_NAME, INDEX_TO_BIGINT_NAME, INDEX_NAME

      execute "DROP INDEX #{UNIQUE_KEYS_INDEX_NAME}"
      rename_index TABLE_NAME, UNIQUE_KEYS_INDEX_NAME_BIGINT, UNIQUE_KEYS_INDEX_NAME
    end
  end
end
