# frozen_string_literal: true

class CreateVulnerabilityArchivalBackupTables < Gitlab::Database::Migration[2.3]
  include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers

  PARTITIONED_TABLE_OPTIONS = {
    primary_key: %i[original_record_identifier date],
    options: 'PARTITION BY RANGE (date)'
  }.freeze

  milestone '18.4'
  skip_require_disable_ddl_transactions!

  def up
    create_partitioned_table(:backup_vulnerabilities)
    create_partitioned_table(:backup_findings, :vulnerability_id)

    create_partitioned_table(:backup_vulnerability_issue_links, :vulnerability_id)
    create_partitioned_table(:backup_vulnerability_external_issue_links, :vulnerability_id)
    create_partitioned_table(:backup_vulnerability_merge_request_links, :vulnerability_id)
    create_partitioned_table(:backup_vulnerability_state_transitions, :vulnerability_id)
    create_partitioned_table(:backup_vulnerability_user_mentions, :vulnerability_id)

    create_partitioned_table(:backup_finding_evidences, :finding_id)
    create_partitioned_table(:backup_finding_flags, :finding_id)
    create_partitioned_table(:backup_finding_identifiers, :finding_id)
    create_partitioned_table(:backup_finding_links, :finding_id)
    create_partitioned_table(:backup_finding_remediations, :finding_id)
    create_partitioned_table(:backup_finding_signatures, :finding_id)
  end

  def down
    drop_table(:backup_vulnerabilities)
    drop_table(:backup_findings)
    drop_table(:backup_vulnerability_issue_links)
    drop_table(:backup_vulnerability_external_issue_links)
    drop_table(:backup_vulnerability_merge_request_links)
    drop_table(:backup_vulnerability_state_transitions)
    drop_table(:backup_vulnerability_user_mentions)
    drop_table(:backup_finding_evidences)
    drop_table(:backup_finding_flags)
    drop_table(:backup_finding_identifiers)
    drop_table(:backup_finding_links)
    drop_table(:backup_finding_remediations)
    drop_table(:backup_finding_signatures)
  end

  private

  def create_partitioned_table(table_name, fk = nil)
    create_table table_name, **PARTITIONED_TABLE_OPTIONS do |t|
      t.timestamps_with_timezone null: false

      t.bigint :original_record_identifier
      t.bigint fk, index: { name: "index_#{table_name}_on_fk" }, null: false if fk
      t.bigint :project_id, index: true, null: false
      t.date :date, null: false
      t.jsonb :data, null: false
    end
  end
end
