Sequel.migration do
  up do
    # 1. Create benchmark_profiles
    create_table(:benchmark_profiles) do
      primary_key :id
			String :label, null: false
			String :settings, null: false
      foreign_key :benchmark_id, :benchmarks, null: false, on_delete: :cascade
			DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
      DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
    end

    # 2. Create join table (tests <-> benchmark_profiles)
    create_table(:benchmark_profiles_tests) do
      primary_key :id
      foreign_key :test_id, :tests, null: false, on_delete: :cascade
      foreign_key :benchmark_profile_id, :benchmark_profiles, null: false, on_delete: :cascade

      index [:test_id, :benchmark_profile_id], unique: true
    end

    # 3. Add benchmark_profile_id to results
    alter_table(:results) do
      add_foreign_key :benchmark_profile_id, :benchmark_profiles, null: true, on_delete: :cascade
    end

    # 4. Migrate data from old schema
		from(:benchmarks).each do |b_row|
      # Create a BenchmarkProfile for this (test, benchmark) pair
      bp_id = self[:benchmark_profiles].insert(
				benchmark_id: b_row[:id],
				label: 'Default',
				settings: '{}'
      )

			from(:benchmarks_tests).each do |bt_row|
				if bt_row[:benchmark_id] == b_row[:id]
		      # Link it to the test
		      self[:benchmark_profiles_tests].insert(
		        test_id: bt_row[:test_id],
		        benchmark_profile_id: bp_id
		      )

		      # Update results belonging to this test + benchmark pair
		      self[:results]
		        .where(test_id: bt_row[:test_id], benchmark_id: bt_row[:benchmark_id])
		        .update(benchmark_profile_id: bp_id)
				end
			end
    end

    # 5. Clean up old schema
    alter_table(:results) do
      drop_foreign_key :benchmark_id
    end

    drop_table(:benchmarks_tests)
  end

  down do
    # 1. Recreate old join table
    create_table(:benchmarks_tests) do
      foreign_key :test_id, :tests, null: false
      foreign_key :benchmark_id, :benchmarks, null: false
    end

    # 2. Add benchmark_id back to results
    alter_table(:results) do
      add_foreign_key :benchmark_id, :benchmarks, null: true
    end

    # 3. Restore data
		from(:benchmark_profiles_tests).each do |bpt_row|
		  bp = self[:benchmark_profiles][id: bpt_row[:benchmark_profile_id]]
		  next unless bp  # safety check

		  # Recreate old benchmarks_tests entry
		  self[:benchmarks_tests].insert(
		    test_id: bpt_row[:test_id],
		    benchmark_id: bp[:benchmark_id]
		  )

		  # Update results to point back to benchmark_id
		  self[:results]
		    .where(test_id: bpt_row[:test_id], benchmark_profile_id: bp[:id])
		    .update(benchmark_id: bp[:benchmark_id])
		end

    # 4. Remove new schema
    alter_table(:results) do
      drop_foreign_key :benchmark_profile_id
    end

    drop_table(:benchmark_profiles_tests)
    drop_table(:benchmark_profiles)
  end
end
