# frozen_string_literal: true

module IncidentManagement
  module OncallRotations
    class PersistShiftsJob
      include ApplicationWorker

      idempotent!
      feature_category :incident_management

      def perform(rotation_id)
        @rotation = ::IncidentManagement::OncallRotation.find_by_id(rotation_id)
        return unless rotation && Gitlab::IncidentManagement.oncall_schedules_available?(rotation.project)

        generated_shifts = generate_shifts
        return unless generated_shifts.present?

        IncidentManagement::OncallShift.bulk_insert!(generated_shifts)
      end

      private

      attr_reader :rotation

      def generate_shifts
        ::IncidentManagement::OncallShiftGenerator
          .new(rotation)
          .for_timeframe(
            starts_at: shift_generation_start_time,
            ends_at: Time.current
          )
      end

      # To avoid generating shifts in the past, which could lead to unnecessary processing,
      # we get the latest of rotation created time, rotation start time,
      # or the most recent shift.
      def shift_generation_start_time
        [
          rotation.created_at,
          rotation.starts_at,
          rotation.shifts.order_starts_at_desc.first&.ends_at
        ].compact.max
      end
    end
  end
end
